繁体   English   中英

如何使用 EF Core 6.0“拆分”表以参与两种不同的关系?

[英]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       |
+----+-------------------------+

任何人都知道我可以使用哪些属性、实体和鉴别器的组合来使其正常工作?

我尝试创建一个SupplierNoteCustomerNote class,它们继承自Note ,然后像这样映射它们:

modelBuilder.Entity<Note>()
  .HasDiscriminator<string>(note => note.EntityType)
  .HasValue<CustomerNote>(nameof(Customer))
  .HasValue<SupplierNote>(nameof(Supplier));

但这会创建一个带有CustomerIdSupplierId列的Note表,这不是我想要的。

任何人都知道我可以使用哪些属性、实体和鉴别器的组合来使其正常工作?

我确信目前不存在这样的组合(截至目前最新的 EFC 6.0 包括在内)。

您正在寻找的内容称为多态关联,并且不受任何 EF(经典或核心)版本的支持。 EF 仅支持可以由关系数据库中的物理强制 FK 约束表示的关联,显然不适用于这些关联。

很快,这是不可能的。 不过,您可以做的最简单的事情是重新访问“我想使用单个数据库表”并只使用单独的表。 由 EF Core 迁移维护的多个表基本上是免费的。 您可以 map 将您的常见 class 作为拥有实体,并将其用作映射到需要它的实体中不同表的拥有实体的集合。 或者您可以尝试将 map 它作为 EFC 5.0 引入的共享实体类型 或者,您可以将它用作基础class (不是entity ),并创建和使用从它派生的具体实体类,无需其他成员。 在所有情况下,它们都将映射到单独的表,但它们的内容将在一个地方定义/维护,并且还可以针对基础 class 进行多态查询/操作(当然,实例创建除外)。

如果你真的想继续使用那个 db model,那么你不能使用导航属性并且必须手动查询/维护它们。 如果有一天(如果有的话)EF 增加了对逻辑关系/导航的支持,请等待。

您将需要创建两个派生类CustomerNote: NoteSupplierNote: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM