如何在实体框架迁移的“一半”多对多上显式设置索引或外键的名称?

Posted

技术标签:

【中文标题】如何在实体框架迁移的“一半”多对多上显式设置索引或外键的名称?【英文标题】:How to set name of index or foreign key explicitly on "half" many-to-many in migration for Entity Framework? 【发布时间】:2021-12-25 23:33:48 【问题描述】:

我有两个这样的课程。

public class Client  public Guid Id  get; set;  ... 
public class Meeting

  public Guid Id  get; set; 
  public Client[] Invitees  get; set;  = new Client[0];
  public Client[] Attendees  get; set;  = new Client[0];

contex中的配置如下。

private static void OnModelCreating(EntityTypeBuilder<Client> entity)  

private static void OnModelCreating(EntityTypeBuilder<Meeting> entity)

    entity.HasMany(a => a.Invitees);
    entity.HasMany(a => a.Attendees);

我只需要我的会议中对客户的参考。客户不需要知道任何事情。会议需要参考客户两次或更少(自愿出席,可选邀请)。

上面的迁移创建了两个表,我对此非常满意。但它也会创建两个索引,就像这样。

migrationBuilder.CreateIndex(
    name: "IX_Clients_MeetingId",
    table: "Clients",
    column: "MeetingId");

migrationBuilder.CreateIndex(
    name: "IX_Clients_MeetingId1",
    table: "Clients",
    column: "MeetingId1");

我对此不太满意。首先,我希望只创建一个索引,因为我们正在索引 sme 表的主键。其次,如果我不能坚持,我不喜欢IX_Clients_MeetingId1 中的数字。

    我可以做什么(如果有的话)只创建一个索引? 如果不使用WithMany(),如何指定索引名称?

我没有提供任何链接作为努力的证明。检查 MSDN、SO 和博客对完整的 M2M 关系产生了很多点击,即.HasMany(...).WithMany(...),这不是我想要的。我看到了一个建议在迁移文件中手动进行更改,但对这些进行调整是在乞求以后的问题。我不知道如何用谷歌搜索不相关的结果,我开始担心我正在尝试的“一半”M2M 是个坏主意(例如,没有创建中间表)。

【问题讨论】:

【参考方案1】:

嗯,似乎 EF 假设您有 2 个 one2many 关系。因此,一位客户最多只能被邀请参加一次会议。

作为一种快速解决方法,您可以

    显式添加 2 个连接实体并配置适当的 one2many 关系。然后你有一张邀请表和一张 出席。 添加一个多对多连接实体,该实体也跟踪一个 链接类型(Client、Meeting、LinkType)以便“受邀”和 “参加”是链接类型 向客户端添加 2 个属性以显示 EF 你的意思是多对多关系:

像这样:

public class Client  
  public Guid Id  get; set; 
  public ICollection<Meeting> InvitedTo  get; set; 
  public ICollection<Meeting> Attended  get; set; 

这些不应显示在客户表中,而是显示为 2 个单独的表。 (本质上是具有隐式连接实体的解决方案 1)

【讨论】:

这与客户不知道链接会议的要求相矛盾,不是吗? 如果 3. 不适合您,那么 1. 或 2. 怎么样? 我倾向于明确的、专用的实体与其类型的连接(如果我没记错的话,你的列表中的#2)。我担心这会造成不必要的复杂性,需要我向一些经验不足的开发者解释。我可以选择在客户端的域对象(即Client 类)中显式添加属性,但在控制器中生成输出到POCO 对象(即ClientDto 类)时不包括它们,这对应于#3在您的列表中。很好的输入,伙计。谢谢。【参考方案2】:

退后一步,我认为您可以通过引入MeetingMember 实体来简单地改进模型。在当前模型中,客户无法被邀请参加两次会议,客户也不能被限制参加他们被邀请参加的会议。所以你需要一个 M2M 关系,如果你使用显式链接实体,你可以侥幸逃脱,比如

MeetingMember(MeetingId, ClientId, InvitedAt, Attended)

【讨论】:

以上是关于如何在实体框架迁移的“一半”多对多上显式设置索引或外键的名称?的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL 数据库上运行迁移时出现实体框架错误。 “空间/全文/哈希索引和显式索引顺序的错误使用”

插入/更新多对多实体框架。我该怎么做?

如何在实体框架中创建多对多映射?

实体框架多对多关系错误

使用实体框架从多对多关系中选择数据

Prisma:在显式多对多关系中创建或连接记录