首页 > 解决方案 > Entity Framework Core 无法确定关系

问题描述

在我的 ASP.Net Core 3.1 应用程序中,我想定义一个 Facility 和一个 Person 模型,其中每个设施可以有一个代表和多个 Person 类型的代表,但我得到“无法确定由导航属性'Facility 表示的关系'List'类型的.Delegates'”错误。

public class Facility
{
    public int Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Activity { get; set; }

    public int RepresentativeId { get; set; }
    public Person Representative { get; set; }

    public List<Person> Delegates { get; set; }
}
public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }

    [InverseProperty("Representative")]
    public List<Facility> RepresentedFacilities { get; set; }
    [InverseProperty("Delegates")]
    public List<Facility> DelegatedToFacilities { get; set; }
}

如何正确完成此映射?我的问题有更好的解决方案吗?

标签: c#asp.net-coreentity-framework-core

解决方案


public class Facility
{  
    ...//other properties
    public List<Person> Delegates { get; set; }
}

public class Person
{ 
    ...//other properties
    [InverseProperty("Representative")]
    public List<Facility> RepresentedFacilities { get; set; }
    [InverseProperty("Delegates")]
    public List<Facility> DelegatedToFacilities { get; set; }
}

在以前版本的实体框架中,这个模型定义(使用上面的代码)足以让 EF 暗示正确的关系类型并为其生成连接表。在 EF Core 直到并包括 3.x 中,需要在模型中包含一个实体来表示连接表,然后将导航属性添加到指向连接实体的多对多关系的任一侧. 因此,请尝试修改您的代码,如下所示:

public class Facility
{
    [Key]
    public int Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Activity { get; set; }
    public int RepresentativeId { get; set; }
    public Person Representative { get; set; }
    public List<PersonFacilities> PersonFacilities { get; set; }
}

public class Person
{
    [Key]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    [InverseProperty("Representative")]
    public List<PersonFacilities> RepresentedFacilities { get; set; }
    [InverseProperty("Delegates")]
    public List<PersonFacilities> DelegatedToFacilities { get; set; }
}

public class PersonFacilities
{
    //public int PersonId { get; set; }
    //public Person Person { get; set; } 
    public int FacilityId { get; set; }
    public Facility Facility { get; set; }

    public int RepresentactivePersonId { get; set; }
    public Person Representative { get; set; }
    public int DelegatePersonId { get; set; }
    public Person Delegates { get; set; }
}

按照惯例,连接表将以连接实体命名。该关系还需要通过 EF Core 的 Fluent API 配置才能成功映射:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<PersonFacilities>().HasKey(pf => new { pf.FacilityId, pf.DelegatePersonId, pf.RepresentactivePersonId });
        modelBuilder.Entity<PersonFacilities>()
            .HasOne(pf => pf.Representative).WithMany(p => p.RepresentedFacilities)
            .HasForeignKey(pf => pf.RepresentactivePersonId).OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<PersonFacilities>().HasOne(pf => pf.Delegates).WithMany(p => p.DelegatedToFacilities)
            .HasForeignKey(pf => pf.DelegatePersonId).OnDelete(DeleteBehavior.Restrict); 
        modelBuilder.Entity<PersonFacilities>().HasOne(pf => pf.Facility).WithMany(p => p.PersonFacilities)
            .HasForeignKey(pf => pf.FacilityId).OnDelete(DeleteBehavior.Restrict);
    }

然后,迁移后,结果如下:

在此处输入图像描述

参考:

在 Entity Framework Core 中配置多对多关系

InverseProperty 属性


推荐阅读