如何使用EF Core加入两个表之间重复关系的信息

时间:2018-04-14 11:04:26

标签: c# entity-framework entity entity-framework-core

我与Person和PersonCompany表之间存在双重关系,其中一个人可以是任何个人或法人,或者是注册为公司的人。 当我需要从银行获取Id 2的Person(Person表)时,EF应该返回与Person表相关的People和PersonsCompany,但这不会发生......我认为问题是因为Person和PersonCompany属性与Person的类型相同。这使得EF了解它们是相同的并且返回与相关PersonCompany不匹配的值。

我是否必须做某种事情"选择"在PersonsCompan导航属性中?有谁知道如何帮助我?

enter image description here



//Get value of table Person
public Pessoa GetById(int id)
        {


            return DbSet
                .Include(pe => pe.Persons)
                    .ThenInclude(p => p.Person)
                .Include(pe => pe.PersonsCompany)
                    .ThenInclude(pe => pe.PersonCmpany)

                //(... other related tables )

                .FirstOrDefault(x => x.PersonId == id);
                
         }






public void Configure(EntityTypeBuilder<PersonEntity> builder)
        {
            builder.ToTable("PersonEntity");

            builder.HasKey(pg => new { pg.PersonId, pg.PersonType});

            builder
               .HasOne(p => p.Person)
               .WithMany(pg => pg.Persons)
               .HasForeignKey(pg => pg.PersonId)
               .OnDelete(DeleteBehavior.ClientSetNull);

            builder.Property(pg => pg.PersonId)
               .HasColumnName("PersonId")
               .HasColumnType("integer")
               .IsRequired();

            builder.Property(pg => pg.PersonType)
               .HasColumnName("PersonTypeId")
               .HasColumnType("integer")
               .IsRequired();

            builder.Property(pg => pg.IdGeneral)
               .HasColumnName("IdGeneral")
               .HasColumnType("integer")
               .IsRequired();

            builder
              .HasOne(f => f.PersonCompany)
              .WithMany(pg => pg.PersonsCompany)
              .HasForeignKey(pg => pg.PersonCompanyId)
              .OnDelete(DeleteBehavior.ClientSetNull);

            builder.Property(pg => pg.PersonCompanyId)
               .HasColumnName("PersonCompanyId")
               .HasColumnType("integer")
               .IsRequired();
           
        }
&#13;
&#13;
&#13;

&#13;
&#13;
 public class Person : Entity
 {
	public virtual ICollection<PersonEntity> Persons { get; private set; }
	public virtual ICollection<PersonEntity> PersonsCompany { get; private set; }
 }
&#13;
&#13;
&#13;

&#13;
&#13;
 public class PersonEntity
    {
        public int Id { get; private set; }
        public int PersonId { get; private set; }
        public int PersonCompanyId { get; private set; }

        public virtual PersonType PersonType { get; private set; }
        public virtual Person Person { get; private set; }
        public virtual Person PersonCompany { get; private set; }
	}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

如果我理解正确,问题与Entity Framework Core: many-to-many self referencing relationship类似,解决方案也是如此。

您案例中的混淆来自集合导航属性名称及其与参考导航属性的映射:

Person.Persons - &gt; PersonEntity.Person

Person.PersonsCompany - &gt; PersonEntity.PersonCompany

你应该像这样重命名:

Person.PersonCompanies - &gt; PersonEntity.Person

Person.CompanyPersons - &gt; PersonEntity.PersonCompany

所以其他引用导航属性表示预期的链接。

E.g。

型号:

public class Person : Entity
{
    public virtual ICollection<PersonEntity> PersonCompanies { get; private set; }
    public virtual ICollection<PersonEntity> CompanyPersons { get; private set; }
}

关系配置:

builder
   .HasOne(p => p.Person)
   .WithMany(pg => pg.PersonCompanies)
   .HasForeignKey(pg => pg.PersonId)
   .OnDelete(DeleteBehavior.ClientSetNull);

builder
  .HasOne(f => f.PersonCompany)
  .WithMany(pg => pg.CompanyPersons)
  .HasForeignKey(pg => pg.PersonCompanyId)
  .OnDelete(DeleteBehavior.ClientSetNull);

用法:

.Include(p => p.PersonCompanies)
    .ThenInclude(pe => pe.PersonCompany)
.Include(p => p.CompanyPersons)
    .ThenInclude(pe => pe.Person)