c# .NET 4.8 如何在 DatabaseContext.cs 中的现有实体上使用默认外键创建多列索引

c# .NET 4.8 How to create multi column index using default foreign keys on existing entity in DatabaseContext.cs

我正在使用 .NET 4.8。我有 3 个表:TableA、TableB 和 TableC。 TableA 已经与 TableB 和 TableC 建立了外键关系。这是使用代码优先迁移完成的。

这是表 A 的代码:

public class TableA : Entity<int>
{
    public bool SomeColumn1 { get; set; }
    public bool SomeColumn2 { get; set; }
    public bool SomeColumn3 { get; set; }

    public virtual TableB TableB { get; set; }
    
    public virtual TableC TableC { get; set; }
}

所以在我的数据库中,TableA 的列 TableB_IdTableC_Id 与各自的表相关。

我想为 TableA 添加一个唯一索引,这样 TableB_IdTableC_Id 的组合是唯一的。

我想在我的 DatabaseContext.cs 文件中使用 FLUENT 模式执行此操作。我在 OnModelCreating() 方法中将其添加到我的 DatabaseContext.cs 中:

modelBuilder.Entity<TableA>().HasIndex(a => new { a.TableB, a.TableC }).IsUnique();

a.TableBa.TableC 是我输入 a. 时唯一可用的选项)

然后我编译我的解决方案并尝试创建一个迁移,但我收到一个错误

Sequence contains no matching element

我发现 this SO post 建议在基本实体中添加值,因此我将 TableA 的代码更改为:

public class TableA : Entity<int>
{
    public bool SomeColumn1 { get; set; }
    public bool SomeColumn2 { get; set; }
    public bool SomeColumn3 { get; set; }

    [Required]
    [Index("IX_TableBAndTableC", 1, IsUnique = true)]
    public int TableB_Id { get; set; }
    public virtual TableB TableB { get; set; }
    
    [Required]
    public int TableC_Id { get; set; }
    [Index("IX_TableBAndTableC", 2, IsUnique = true)]
    public virtual TableC TableC { get; set; }
}

TableB_IdTableC_Id 现在可以在 DatabaseContext.cs 的代码中使用,但是当我编译解决方案并创建迁移时,它会删除现有的 TableB_IdTableC_Id 表 A 上的列并将它们替换为 TableB_Id1TableC_Id1,然后创建索引。

然后我发现 this SO post 建议向基本实体添加外键装饰器,所以我注释掉了我的 DatabaseContext.cs 文件中的代码,并将我的 TableA 实体中的代码更改为:

public class TableA : Entity<int>
{
    public bool SomeColumn1 { get; set; }
    public bool SomeColumn2 { get; set; }
    public bool SomeColumn3 { get; set; }

    [ForeignKey("TableB_Id")]
    public virtual TableB TableB { get; set; }
    
    [ForeignKey("TableC_Id")]
    public virtual TableC TableC { get; set; }
}

但是当我编译解决方案并生成迁移时,迁移是空的,up()down() 方法中没有任何内容。

我在官方文档中进行了搜索,但没有找到任何关于如何使用默认列创建多列唯一索引的具体说明,这些默认列是在我使用代码优先迁移设置外键时创建的( TableA.TableB_IdTableA.TableC_Id)。 TableA.TableB_IdTableA.TableC_Id 列由 entity framework 自动创建,因此我无法在我的 DatabaseContext.cs 文件中直接使用它们。

请有人帮我弄清楚如何通过向 [=19= 添加一些内容来在这两个默认外键 TableB_IdTableC_Id 上创建多列唯一索引] 文件或 TableA 的基本实体代码,或两者兼而有之。

正确、解释清楚的答案将被标记为已接受和点赞。谢谢

玩弄之后,我发现 this page 在 entity framework 中讨论了外键关系。在这里,我找到了一种不同的方式来为我的 TableA 实体格式化我的代码,这将完成我需要做的事情。

所以这是我的 TableA 实体的代码:

public class TableA : Entity<int>
{
    public bool SomeColumn1 { get; set; }
    public bool SomeColumn2 { get; set; }
    public bool SomeColumn3 { get; set; }

    [ForeignKey("TableB")]
    public int TableB_Id { get; set; }
    public virtual TableB TableB { get; set; }
        
    [ForeignKey("TableC")]
    public int TableC_Id { get; set; }
    public virtual TableC TableC { get; set; }
}

这与我在最初 post 中尝试的一种方法非常相似,我只是有一些设置不正确。

在我将此代码添加到我的 TableA 实体后,回到我的 DatabaseCOntext.cs 文件中,我能够在 OnModelCreating() 方法中添加此行:

modelBuilder.Entity<TableA>().HasIndex(a => new { a.TableB_Id, a.TableC_Id }).IsUnique();

现在指向以前不可用的字段 TableA.TableB_IdTableA.TableC_Id

我编译了我的解决方案并创建了一个新的迁移,它似乎可以完成我需要的一切。

我再次编译了解决方案,运行 迁移和列 TableA.TableB_IdTableA.TableC_Id 仍然存在,设置为它们各自表的外键并且有一个唯一的对它们的约束不允许插入重复行。

我希望这对其他人有帮助。如果我做的不清楚,请发表评论,我会尽力澄清。