【问题标题】:Making two columns unique when jointly compounded using Entity Framework使用实体框架联合复合时使两列唯一
【发布时间】:2021-08-17 14:34:50
【问题描述】:

我有两列分别称为 MonkeyDonkey。两者都是非空的,即null 是不允许的。设置声明如下。

protected override void OnModelCreating(ModelBuilder builder)
{
  base.OnModelCreating(builder);
  ...
  builder.Entity<Thing>()
    .Property(a => a.Monkey)
    .IsRequired();
  builder.Entity<Thing>()
    .Property(a => a.Donkey)
    .IsRequired();
}

现在,我了解到组合的内容必须是唯一的,即没有记录可能具有相同的猴子和驴。根据MSDN(多个道具的索引),我应该使用HasColumnAnnotation 并传递IndexAnnotation 的实例。在this answer 中也建议使用System.Data.Entity.Infrastructure.Annotations 中的IndexAnnotation.AnnotationName

问题是我找不到那个方法,只能看到HasAnnotation。我不清楚它是否是更新的版本(因为链接到的帖子现在有点过时了)。我也无法访问 using 语句中的命名空间 Entity

builder.Entity<Thing>()
  .Property(a => a.Monkey)
  .HasAnnotation(...);

这是正确的方法还是我应该继续寻找其他注释方法?获取命名空间缺少什么?索引是否适合开始?

我也尝试过使用 index,但这需要我声明一个专门的类,这看起来很笨重,并且表明这是错误的方法。

builder.Entity<Thing>()
  .HasIndex(a => new IndexDedicatedClass(a.Monkey, a.Donkey))
  .IsUnique();

【问题讨论】:

  • ASP.NET Core 3.1 仅随 EF Core 3.1 提供,MSDN 链接适用于 EF6,请参阅 this

标签: c# entity-framework asp.net-core-3.1


【解决方案1】:

您可以添加一个跨多列的复合索引,然后将其标记为唯一,这会在数据库上创建一个唯一索引。

modelBuilder.Entity<Thing>(builder =>
{
    builder
        .HasIndex(e => new { e.Monkey, e.Donkey })
        .IsUnique();
});

这实际上有助于确保($monkey, $donkey) 元组不会在表中出现两次。

更多信息

【讨论】:

  • 啊,我喜欢这种方法,但没有意识到我可以为此目的使用匿名类。现在我看到了,这有点明显。我想我陷入了硬式思维。这种方法对性能影响很大还是完全等同于使用纯 SQL 设置复合键?
  • 它转换为纯 SQL。生成一个迁移,然后是它的 sql 脚本,你会看到一个 CREATE UNIQUE INDEX $name ON $table($col1, $col2) 语句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
相关资源
最近更新 更多