entity-framework - 联接表中的代码优先Fluent API和导航属性

标签 entity-framework code-first composite-key jointable

我有四个实体,我想先通过代码流利的api将其转换为数据库表(我使用的是在databaseanswers.org上找到的模型),但不确定如何。我遇到的问题是,SuggestedMenuId正在复合键(MenuCourse和CourseRecipeChoice)中的两个不同表之间迁移。

这是我收到的消息:

“在模型生成过程中检测到一个或多个验证错误:

\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; 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; }
}

键如下:
  • 建议菜单(Id)
  • 菜单类(class)(ID,SuggestedMenuId)
  • CourseRecipeChoice(Id,SuggestedMenuId,MenuCourseId,RecipeId)//这实际上让我感到困惑,因为根据模型,SuggestedMenuId是SuggestedMenu中的PK,而MenuCourse和CourseRecipeChoice中的PF(这可能是错误的设计吗?)
  • 配方(RecipeId)
  • 最佳答案

    ...根据手头的信息(键,关系尚不完全清楚),
    这是最复杂的情​​况,应该涵盖您可能的想法...

    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; }
    }
    

    ...以及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 );
    

    ...并进行测试就像是...
            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);
                }
            }
    

    关于entity-framework - 联接表中的代码优先Fluent API和导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10154512/

    相关文章:

    entity-framework - Entity Framework 标量函数映射

    wcf - 自跟踪实体 - AcceptChanges 无法继续,因为对象的键值与 ObjectStateManager 中的另一个对象冲突

    c# - EF 异常 - InvalidOperationException : The 'x' property on 'y' could not be set to a 'String' value

    c# - 为什么代码首先要创建索引列?

    nhibernate - NHibernate的复合键/ID映射

    ravendb - 如何在 RavenDB 中使用引用类型作为文档中的键

    c# - 属性 'Dish_ID' 不能用作实体的关键属性

    entity-framework-4 - EF CTP4 - 创建表,但不删除数据库

    .net - Entity Framework 和代码优先开发

    sql-server - 数据库设计-复合键关系问题