[英]How can I "split" a table using EF Core 6.0 to participate in two different relationships?
我需要在我的 EF Core 6 数据 model 中向多个实体添加“注释”。 笔记具有完全相同的架构——日期/时间、创建笔记的人的姓名和评论——所以我想使用单个数据库表,每个Note
记录上都有一个鉴别器列,指示哪个关系/它所属的实体。
我的实体 model 看起来像这样:
public class Note {
public int Id { get; set; }
public DateTime CreatedAt { get; set;}
pulic string CreatedBy { get; set; }
public string Comments { get; set; }
}
public class Customer {
public int Id { get; set; }
public string Name { get; set; }
public List<Note> Notes { get; set; }
}
public class Supplier {
public int Id { get; set; }
public string Name { get; set; }
public List<Note> Notes { get; set; }
}
我正在尝试 map 我的DbContext
上的适当属性来生成这组表:
Notes
+----+------------+----------+------------------+------------+----------------------------------+
| Id | EntityType | EntityId | CreatedAt | CreatedBy | Comments |
+----+------------+----------+------------------+------------+----------------------------------+
| 1 | Customer | 17 | 2022-01-22T18:22 | alice | Cancelled erroneous invoice |
| 2 | Supplier | 19 | 2022-01-23T12:52 | bob | Amended booking date to April |
| 3 | Customer | 24 | 2022-01-24T19:07 | bob | Refunded duplicated order |
| 4 | Customer | 17 | 2022-01-27T18:22 | alice | Added Bryan Smith as contact |
| 5 | Supplier | 22 | 2022-01-27T20:17 | carol | Override booking terms for 2022 |
+----+------------+----------+------------------+------------+----------------------------------+
Customers
+----+------------------+
| Id | Name |
+----+------------------+
| 17 | Fisher Price Plc |
| 24 | Bob's Bikes Ltd |
+----+------------------+
Suppliers
+----+-------------------------+
| Id | Name |
+----+-------------------------+
| 19 | Wigs'r'Us International |
| 22 | Monkeys Unlimited |
+----+-------------------------+
任何人都知道我可以使用哪些属性、实体和鉴别器的组合来使其正常工作?
我尝试创建一个SupplierNote
和CustomerNote
class,它们继承自Note
,然后像这样映射它们:
modelBuilder.Entity<Note>()
.HasDiscriminator<string>(note => note.EntityType)
.HasValue<CustomerNote>(nameof(Customer))
.HasValue<SupplierNote>(nameof(Supplier));
但这会创建一个带有CustomerId
和SupplierId
列的Note
表,这不是我想要的。
任何人都知道我可以使用哪些属性、实体和鉴别器的组合来使其正常工作?
我确信目前不存在这样的组合(截至目前最新的 EFC 6.0 包括在内)。
您正在寻找的内容称为多态关联,并且不受任何 EF(经典或核心)版本的支持。 EF 仅支持可以由关系数据库中的物理强制 FK 约束表示的关联,显然不适用于这些关联。
很快,这是不可能的。 不过,您可以做的最简单的事情是重新访问“我想使用单个数据库表”并只使用单独的表。 由 EF Core 迁移维护的多个表基本上是免费的。 您可以 map 将您的常见 class 作为拥有实体,并将其用作映射到需要它的实体中不同表的拥有实体的集合。 或者您可以尝试将 map 它作为 EFC 5.0 引入的共享实体类型。 或者,您可以将它用作基础class (不是entity ),并创建和使用从它派生的具体实体类,无需其他成员。 在所有情况下,它们都将映射到单独的表,但它们的内容将在一个地方定义/维护,并且还可以针对基础 class 进行多态查询/操作(当然,实例创建除外)。
如果你真的想继续使用那个 db model,那么你不能使用导航属性并且必须手动查询/维护它们。 如果有一天(如果有的话)EF 增加了对逻辑关系/导航的支持,请等待。
您将需要创建两个派生类CustomerNote: Note
和SupplierNote: Note
,每个类都有自己的类型绑定。 您甚至可以创建一个通用的派生类型,尽管这可能会过度工程化。 两者都将组合在一个Note
表中,因为默认情况下 EF 使用一个表每个层次结构( 链接)。 这将向表中添加一个鉴别器。
namespace EFExample
{
public abstract class NoteBase
{
public int Id { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.Now;
public string CreatedBy { get; set; }
public string Comments { get; set; }
}
public class Note<T> : NoteBase
{
public virtual T Owner { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public List<Note<Customer>> Notes { get; set; } = new();
}
public class Supplier
{
public int Id { get; set; }
public string Name { get; set; }
public List<Note<Supplier>> Notes { get; set; } = new();
}
}
上下文将只有三个实体
public DbSet<NoteBase> Notes { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
以这种方式添加有点冗长,所以也许SupplierNote
不是一个坏主意
context.Add(new Supplier
{
Notes = new List<Note<Supplier>> {
new Note<Supplier>
{
CreatedBy = "Me",
Comments = "Hello",
}
}
});
context.SaveChanges();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.