带有两个相同类型实体的EF Core Fluent API的映射关系

时间:2019-07-19 21:06:18

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

我一直在尝试使用流畅的api为下面的图像配置适当的映射。 (如果有人将其标记为重复,出于对圣洁事物的热爱,请提供相关链接!我花了几天的时间来整理stackoverflow。)

Table Map

我主要针对的是所有实体都有一个 EnterpriseID ,可用作分片密钥。

企业表包含两个联系人,一个主要联系人和一个BillingContact。

我想做的是创建一个新的Enterprise,使用生成的代码 GUID ID以及两个联系人(主要和帐单),分配 Enterprise ID ,然后在 TrackingState 上调用SaveChanges。添加了对象层次结构(此时为Enterprise-> Contacts-> Addresses。

在没有任何Fluent映射的情况下, EF Core 2.1表示。““联系人”和“ Enterprise.BillingContact”之间以及“联系人”和“ Enterprise.PrimaryContact”之间的关系都可以使用{'< strong> EnterpriseID '}作为外键。要解决此问题,请至少在一种关系上显式配置外键属性。“

我尝试了许多配置,或者最终选择了仅在Enterprise表中定义了Contact属性之一的DB,或者整个混乱变成了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;}
}

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

1 个答案:

答案 0 :(得分:1)

  

Enterprise表包含两个联系人,一个是主要联系人,另一个是一个BillingContact。

然后,EnterpriseContactAddress之间的关系应如下:

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);
}