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

问题描述

我有四个实体,我想通过代码第一流利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和导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-08 01:48