简体   繁体   English

多对多 EF 核心 - 无法确定关系

[英]Many to many EF core - Unable to determine the relationship

I'm trying to solve a many to many relationship in EF core, but I keep getting an exception (Unable to determine the raltionship represented by navigation property 'Category.contacts' of type List)我正在尝试解决 EF 核心中的多对多关系,但我不断收到异常(无法确定列表类型的导航属性“Category.contacts”表示的关系)

I'm learning EF core and I've read a lot of posts about this issue already but I cannot solve it on my own.我正在学习 EF 核心,我已经阅读了很多关于这个问题的帖子,但我无法自己解决。 I believe it will be asked on the exam.相信考试会问的。

I've made a class to solve the many to many problem, but how do I configure this correctly using the fluent api?我已经创建了一个类来解决多对多问题,但是如何使用 fluent api 正确配置它?

This is my code:这是我的代码:

public class Contact{
    public int PersonId {get; set;}
    public List<Category> Categories {get; set;}
}

public class Category{
    public int CategoryId {get; set;}
    public List<Category> Categories {get; set;}
}

public class ContactCategory{
    public int PersonId {get; set;}
    public int CategoryId {get; set;}
    public Contact Contact {get; set;}
    public Category Category {get; set;}
}

//Inside the DbContext class:
protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<ContactCategory>().HasKey(x => new {x.PersonId, x.CategoryId});
}

The exception itself:异常本身:

Unhandled Exception: System.TypeInitializationException: The type initializer for 'Contacts.UI.CA.Program' threw an exception.未处理的异常:System.TypeInitializationException:“Contacts.UI.CA.Program”的类型初始值设定项引发异常。 ---> System.InvalidOperationException: Unable to determine the relationship represented by navigation property 'Category.Contacts' of type 'List'. ---> System.InvalidOperationException: 无法确定由“List”类型的导航属性“Category.Contacts”表示的关系。 Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。

The many-to-many relationship is a tricky one;多对多关系是一个棘手的关系。 we need to understand how these kinds of relationships are built.我们需要了解这些关系是如何建立的。 Usually, we will build two different entities that require a many-to-many relationship, create an entity that will be purely used to join the first two entities, and then map one-to-many between this entity (created to join two separate one-to-many relationships) and the two entities (created first) separately:通常,我们会构建两个需要多对多关系的不同实体,创建一个实体,将纯粹用于连接前两个实体,然后在此实体之间进行一对多映射(创建用于连接两个独立的实体)一对多关系)和两个实体(首先创建)分别:

public class Contact
{
    public int Id {get; set;}
    public ICollection<ContactCategory> ContactCategories {get; set;}
}

public class Category
{
    public int Id { get; set; }
    public ICollection<ContactCategory> ContactCategories { get; set; }
}

public class ContactCategory
{
    public int Id { get; set; }
    public int ContactId {get; set;}
    public Contact Contact {get; set;}
    public int CategoryId {get; set;}
    public Category Category {get; set;}
}

The Contact and Category entities require many-to-many relationships for which the ContactCategory entity is created, and its only job is to join the Contact and Category entities. ContactCategory实体需要创建ContactCategory实体的多对多关系,它的唯一工作是连接 Contact 和 Category 实体。

We should configure the relationship in the Fluent API in two different one-to-many relationships between the Contact and ContactCategory and Category and ContactCategory entities.我们应该在 Contact 和 ContactCategory 以及 Category 和 ContactCategory 实体之间的两种不同的一对多关系中配置 Fluent API 中的关系。 The HasForeignKey method doesn't need to be generic, since one-to-many relationships don't need to mark the dependent type explicitly: HasForeignKey 方法不需要是通用的,因为一对多关系不需要显式标记依赖类型:

The many-to-many relationship between Contact and Category entities require the following configuration: Contact 和 Category 实体之间的多对多关系需要如下配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<ContactCategory>()
    .HasOne(x => x.Category)
    .WithMany(x => x.ContactCategories)
    .HasForeignKey(x => x.CategoryId);

  modelBuilder.Entity<ContactCategory>()
    .HasOne(x => x.Contact)
    .WithMany(x => x.ContactCategories)
    .HasForeignKey(x => x.ContactId);
}

Good luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM