首页 > 解决方案 > 使用 EF Core Fluent API 与两个相同类型的实体映射关系

问题描述

我一直在尝试使用 fluent api 为下图配置适当的映射。(如果有人将此标记为重复,出于对所有神圣事物的热爱,请附上相关链接!我花了几天时间梳理 stackoverflow。)

表地图

我的主要目标是所有实体都将有一个EnterpriseID用作分片键。

Enterprise 表包含两个联系人,一个 PrimaryContact 和一个 BillingContact。

我想做的是使用代码生成的GUID ID 以及两个联系人(主要和计费)创建一个新企业,将企业 ID分配给这些并在TrackingState上调用 SaveChanges 。添加的对象层次结构(此时是企业->联系人->地址。

在没有任何 Fluent 映射的情况下,EF Core 2.1 说..“'Contact' 和 'Enterprise.BillingContact' 之间以及 'Contact' 和 'Enterprise.PrimaryContact' 之间的关系都可以使用 {' EnterpriseID '} 作为外键。要解决这个问题至少在其中一个关系上显式配置外键属性。”

我尝试了许多配置,要么最终得到一个只定义了 Enterprise 表中的一个 Contact 属性的数据库,要么整个混乱都变成了 FK / 循环地狱。

这是当前的类存根..

public class Enterprise
{
  public Guid ID {get; set;}
  public Contact PrimaryContact {get; set;}
  public Contact BillingContact {get; set;}
}

public class Contact
{
  public Guid ID {get; set;}
  public Guid EnterpriseID {get; set;}
  public string FName {get; set;}
  public string LName {get; set;}
  public Address Address {get; set;}
}

public class Store
{
  public Guid ID {get; set;}
  public Guid EnterpriseID {get; set;}
  public Contact PrimaryContact {get; set;}
}

public class Order
{
  public Guid ID {get; set;}
  public Guid EnterpriseID {get; set;}
  public Guid StoreID {get; set;}
  public Contact CustomerContact {get; set;}
}

public class Address
{
  public Guid ID {get; set;}
  public Guid EnterpriseID {get; set;}
  public string Lines {get; set;}
}

我真的很感激一些关于如何配置它的建议。

标签: entity-framework-coreef-core-2.1

解决方案


Enterprise 表包含两个联系人,一个 PrimaryContact 和一个 BillingContact。

Enterprise那么,Contact和之间的关系Address应该如下:

public class Enterprise
{
    [Key]
    public Guid ID { get; set; }

    public Guid PrimaryContactId { get; set; }
    public Contact PrimaryContact { get; set; }

    public Guid BillingContactId { get; set; }
    public Contact BillingContact { get; set; }
}

public class Contact
{
    [Key]
    public Guid ID { get; set; }
    public string FName { get; set; }
    public string LName { get; set; }

    public Address Address {get; set;}
}

public class Address
{
   [Key]
   public Guid ContactId {get; set;}
   public string Lines {get; set;}
}

然后在Fluent API配置中:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Enterprise>().HasOne(e => e.PrimaryContact)
            .WithOne()
            .HasForeignKey<Enterprise>(e => e.PrimaryContactId).OnDelete(DeleteBehavior.Restrict);

    modelBuilder.Entity<Enterprise>().HasOne(e => e.BillingContact)
            .WithOne()
            .HasForeignKey<Enterprise>(e => e.BillingContactId).OnDelete(DeleteBehavior.Restrict);

   modelBuilder.Entity<Contact>().HasOne(c => c.Address)
            .WithOne().HasForeignKey<Address>(a => a.ContactId);
}

推荐阅读