entity-framework-core - 使用 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;}
}
我真的很感激一些关于如何配置它的建议。
解决方案
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);
}
推荐阅读
- python - 使用 selenium 启动 firefox,包括 firefox 附加组件
- java - 递归列表 - 计算直到最后一次出现并包括最后一次出现的所有元素的总和
- python - 难以理解为什么一个类的两个实例共享同一个内部对象
- python - 如何获取 csv 网址
- python - 海龟动画随机加速/减速
- firebase - 使用 Firebase 在 TextField 中保留换行符
- android - 除了检查 sdk 路径和卸载 avast 之外,如何解决“无法定位 adb 问题”
- javascript - 在 Node.js 中调用我的一个函数时,程序首先调用 emitHookFactory 并陷入无限循环
- java - 使用 Spring Boot 从 Kafka 队列消费时获取序列化异常
- python - 将 Hessian 定义为零