问题描述
我有四个实体,我想通过代码第一流利api(我使用在databaseanswers.org找到的模型)翻译成数据库表,但我不确定如何。我遇到的问题是SuggestedMenuId正在复合键(MenuCourse和CourseRecipeChoice)中的两个不同的表中进行迁移。这是我得到的消息: / p>
在模型生成期间检测到一个或多个验证错误:
\tSystem.Data.Entity.Edm .EdmAssociationConstraint::关系约束中从属和主体角色中的属性数必须相同。
这是我在EntityTypeConfiguration类中尝试过的,它是显然不正确...
public class CourseRecipeChoiceConfiguration:EntityTypeConfiguration< CourseRecipeChoice>
{
public CourseRecipeChoiceConfiguration()
{
HasKey(crc => new {crc.Id});
HasRequired(r => r.Recipe).WithMany(crc => crc.CourseRecipeChoices).HasForeignKey(crc => crc.RecipeId);
HasRequired(m => m.MenuCourse).WithMany(crc => crc.CourseRecipeChoices).HasForeignKey(crc => crc.MenuCourseId);
HasRequired(m => m.MenuCourse).WithMany(crc => crc.CourseRecipeChoices).HasForeignKey(crc => crc.SuggestedMenu_MenuCourseId);
}
}
导航属性和用于CourseRecipeChoice连接表流畅api语法的正确语法?
public class SuggestedMenu
{
public int SuggestedMenuId {get;组; }
public virtual ICollection< MenuCourse> MenuCourses {get;组; }
}
public class MenuCourse
{
public int Id {get;组; }
public int SuggestedMenuId {get;组; }
public SuggestedMenu SuggestedMenu {get;组; }
public virtual ICollection< CourseRecipeChoice> CourseRecipeChoices {get;组; }
}
public class CourseRecipeChoice
{
public int SuggestedMenuId {get;组; }
public int MenuCourseId {get;组; }
public int Id {get;组; }
public int RecipeId {get;组; }
//如何表示此类中的导航属性?
}
public class配方
{
public int RecipeId {get;组; }
public string Name {get;组; }
public string描述{get;组; }
public ICollection< CourseRecipeChoice> CourseRecipeChoices {get;组;
}
密钥如下:
- SuggestedMenu(Id)
- MenuCourse(Id,SuggestedMenuId) li>
- CourseRecipeChoice(Id,SuggestedMenuId,MenuCourseId,RecipeId) //这实际上是在我被困惑的地方,因为根据模型,SuggestedMenuId是SuggestedMenu中的PK和PF在MenuCourse和CourseRecipeChoice(这可能只是坏的设计?)
- 配方(RecipeId)
...根据手头的信息(键,关系不完全清楚),
这里是最复杂的场景并且应该涵盖你可能有的想法...
public class SuggestedMenu
{
public int SuggestedMenuId {get;组; }
public string描述{get;组; }
public virtual ICollection< MenuCourse> MenuCourses {get;组; }
// public virtual ICollection< CourseRecipeChoice> CourseRecipeChoices {get;组; }
}
public class MenuCourse
{
public int MenuCourseId {get;组; }
public int SuggestedMenuId {get;组; }
public SuggestedMenu SuggestedMenu {get;组; }
public virtual ICollection< CourseRecipeChoice> CourseRecipeChoices {get;组;
}
public class CourseRecipeChoice
{
public int CourseRecipeChoiceId {get;组; }
public int MenuCourseId {get;组; }
public int SuggestedMenuId {get;组; }
public int RecipeId {get;组; }
//如果需要,没有虚拟的,非可选的
public Recipe Recipe {get;组; }
public MenuCourse MenuCourse {get;组; }
// public SuggestedMenu SuggestedMenu {get;组;
}
public class Recipe
{
public int RecipeId {get;组; }
public string Name {get;组; }
public string描述{get;组; }
public virtual ICollection< CourseRecipeChoice> CourseRecipeChoices {get;组;
}
...和 OnModelCreating
(我更喜欢所有配置在那里,虽然是一样的)...
modelBuilder.Entity< CourseRecipeChoice> ;()
.HasKey(crc => new {crc.CourseRecipeChoiceId,crc.SuggestedMenuId,crc.MenuCourseId,crc.RecipeId});
modelBuilder.Entity< CourseRecipeChoice>()
.HasRequired(r => r.Recipe)
.WithMany(crc => crc.CourseRecipeChoices)
.HasForeignKey(crc => crc.RecipeId)
.WillCascadeOnDelete(false);
modelBuilder.Entity< CourseRecipeChoice>()
.HasRequired(m => m.MenuCourse)
.WithMany(crc => crc.CourseRecipeChoices)
.HasForeignKey(crc => new {crc.MenuCourseId,crc.SuggestedMenuId})
.WillCascadeOnDelete(false);
modelBuilder.Entity< SuggestedMenu>()
.HasKey(crc => crc.SuggestedMenuId);
modelBuilder.Entity< MenuCourse>()
.HasKey(crc => new {crc.MenuCourseId,crc.SuggestedMenuId});
modelBuilder.Entity< MenuCourse>()
.HasRequired(m => m.SuggestedMenu)
.WithMany(crc => crc.MenuCourses)
.HasForeignKey(crc => crc.SuggestedMenuId)
.WillCascadeOnDelete(false);
modelBuilder.Entity< Recipe>()
.HasKey(crc => crc.RecipeId);
...并测试例如像$ ...
$ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ = new SuggestedMenu {Description =建议菜单};
var menucourse = new MenuCourse {MenuCourseId = 2,SuggestedMenu = suggestmenu};
var recipe = new Recipe {Name =我的食谱,描述=recipe desc};
var crc = new CourseRecipeChoice {CourseRecipeChoiceId = 2,MenuCourse = menucourse,Recipe = recipe,};
db.CourseRecipeChoices.Add(crc);
int recordsAffected = db.SaveChanges();
foreach(var crcs in db.CourseRecipeChoices.Include(c => c.MenuCourse).Include(c => c.Recipe))
{
Console.WriteLine({ 0},{1},{2},{3},crcs.MenuCourse.MenuCourseId,crcs.MenuCourse.SuggestedMenuId,crcs.Recipe.Name,crcs.Recipe.Description);
}
}
I have four entities that I would like to translate into database tables via code first fluent api (I'm using a model found at databaseanswers.org), but I'm not certain as to how. The problem I'm having is that SuggestedMenuId is being migrated across two different tables in a Composite key (MenuCourse and CourseRecipeChoice).
Here's the message I'm getting:
"One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmAssociationConstraint: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical."
Here's what I've tried in my EntityTypeConfiguration class and it's obviously incorrect...
public class CourseRecipeChoiceConfiguration : EntityTypeConfiguration<CourseRecipeChoice>
{
public CourseRecipeChoiceConfiguration()
{
HasKey(crc => new { crc.Id});
HasRequired(r => r.Recipe).WithMany(crc => crc.CourseRecipeChoices).HasForeignKey(crc => crc.RecipeId);
HasRequired(m => m.MenuCourse).WithMany(crc => crc.CourseRecipeChoices).HasForeignKey(crc => crc.MenuCourseId);
HasRequired(m => m.MenuCourse).WithMany(crc => crc.CourseRecipeChoices).HasForeignKey(crc => crc.SuggestedMenu_MenuCourseId);
}
}
What is the correct syntax for the navigation properties and the correct syntax for fluent api syntax for the CourseRecipeChoice join table?
public class SuggestedMenu
{
public int SuggestedMenuId { get; set; }
public virtual ICollection<MenuCourse> MenuCourses { get; set; }
}
public class MenuCourse
{
public int Id { get; set; }
public int SuggestedMenuId { get; set; }
public SuggestedMenu SuggestedMenu { get; set; }
public virtual ICollection<CourseRecipeChoice> CourseRecipeChoices { get; set; }
}
public class CourseRecipeChoice
{
public int SuggestedMenuId { get; set; }
public int MenuCourseId { get; set; }
public int Id { get; set; }
public int RecipeId { get; set; }
//How do I represent the navigation properties in this class?
}
public class Recipe
{
public int RecipeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<CourseRecipeChoice> CourseRecipeChoices { get; set; }
}
The keys are as follows:
- SuggestedMenu(Id)
- MenuCourse(Id, SuggestedMenuId)
- CourseRecipeChoice(Id, SuggestedMenuId, MenuCourseId, RecipeId) //this is actually where I get confused because according to the model, SuggestedMenuId is a PK in SuggestedMenu and a PF in MenuCourse and CourseRecipeChoice (could this just be bad design?)
- Recipe(RecipeId)
...based on the info at hand (keys, relationships are not entirely clear),
here is the most complex scenario and should cover what you might have I think...
public class SuggestedMenu
{
public int SuggestedMenuId { get; set; }
public string Description { get; set; }
public virtual ICollection<MenuCourse> MenuCourses { get; set; }
// public virtual ICollection<CourseRecipeChoice> CourseRecipeChoices { get; set; }
}
public class MenuCourse
{
public int MenuCourseId { get; set; }
public int SuggestedMenuId { get; set; }
public SuggestedMenu SuggestedMenu { get; set; }
public virtual ICollection<CourseRecipeChoice> CourseRecipeChoices { get; set; }
}
public class CourseRecipeChoice
{
public int CourseRecipeChoiceId { get; set; }
public int MenuCourseId { get; set; }
public int SuggestedMenuId { get; set; }
public int RecipeId { get; set; }
// no virtuals if required, non-optional
public Recipe Recipe { get; set; }
public MenuCourse MenuCourse { get; set; }
// public SuggestedMenu SuggestedMenu { get; set; }
}
public class Recipe
{
public int RecipeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<CourseRecipeChoice> CourseRecipeChoices { get; set; }
}
...and in OnModelCreating
(I prefer it all config done there, though it's the same)...
modelBuilder.Entity<CourseRecipeChoice>()
.HasKey(crc => new { crc.CourseRecipeChoiceId, crc.SuggestedMenuId, crc.MenuCourseId, crc.RecipeId });
modelBuilder.Entity<CourseRecipeChoice>()
.HasRequired(r => r.Recipe)
.WithMany(crc => crc.CourseRecipeChoices)
.HasForeignKey(crc => crc.RecipeId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<CourseRecipeChoice>()
.HasRequired(m => m.MenuCourse)
.WithMany(crc => crc.CourseRecipeChoices)
.HasForeignKey(crc => new { crc.MenuCourseId, crc.SuggestedMenuId })
.WillCascadeOnDelete(false);
modelBuilder.Entity<SuggestedMenu>()
.HasKey(crc => crc.SuggestedMenuId );
modelBuilder.Entity<MenuCourse>()
.HasKey(crc => new { crc.MenuCourseId, crc.SuggestedMenuId });
modelBuilder.Entity<MenuCourse>()
.HasRequired(m => m.SuggestedMenu)
.WithMany(crc => crc.MenuCourses)
.HasForeignKey(crc => crc.SuggestedMenuId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Recipe>()
.HasKey(crc => crc.RecipeId );
...and to test e.g. something like...
using (var db = new YourDbContext())
{
SuggestedMenu suggestedmenu = new SuggestedMenu { Description = "suggested menu" };
var menucourse = new MenuCourse { MenuCourseId = 2, SuggestedMenu = suggestedmenu };
var recipe = new Recipe { Name = "My recipe", Description = "recipe desc" };
var crc = new CourseRecipeChoice { CourseRecipeChoiceId = 2, MenuCourse = menucourse, Recipe = recipe, };
db.CourseRecipeChoices.Add(crc);
int recordsAffected = db.SaveChanges();
foreach (var crcs in db.CourseRecipeChoices.Include(c => c.MenuCourse).Include(c => c.Recipe))
{
Console.WriteLine("{0}, {1}, {2}, {3}", crcs.MenuCourse.MenuCourseId, crcs.MenuCourse.SuggestedMenuId, crcs.Recipe.Name, crcs.Recipe.Description);
}
}
这篇关于连接表中的Code First Fluent API和导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!