连接表中的 Code First Fluent API 和导航属性 [英] Code First Fluent API and Navigation Properties in a Join Table

查看:25
本文介绍了连接表中的 Code First Fluent API 和导航属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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).

这是我收到的消息:

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

"One or more validation errors were detected during model generation:

System.Data.Entity.Edm.EdmAssociationConstraint:: 关系约束中的从属角色和主体角色中的属性数量必须相同."

System.Data.Entity.Edm.EdmAssociationConstraint: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical."

这是我在我的 EntityTypeConfiguration 类中尝试过的,它显然不正确......

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

导航属性的正确语法和CourseRecipeChoice 连接表的流畅api 语法的正确语法是什么?

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

键如下:

  • 建议菜单(ID)
  • MenuCourse(Id, SuggestedMenuId)
  • CourseRecipeChoice(Id, SuggestedMenuId, MenuCourseId, RecipeId)//这实际上是我感到困惑的地方,因为根据模型,SuggestedMenuId 是 SuggestedMenu 中的 PK 和 MenuCourse 和 CourseRecipeChoice 中的 PF(可以这只是糟糕的设计吗?)
  • 食谱(RecipeId)
  • 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; }
}

...并且在 OnModelCreating 中(我更喜欢在那里完成所有配置,尽管它是相同的)...

...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 和导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆