在 EF Core 中生成复合唯一约束/索引
Posted
技术标签:
【中文标题】在 EF Core 中生成复合唯一约束/索引【英文标题】:Generate a composite unique constraint/index, in EF Core 【发布时间】:2017-04-07 16:05:06 【问题描述】:我需要为我的实体的 Name
属性设置一个复合唯一约束,该约束在 Category
中是唯一的(它有一个 FK)。
所以是这样的:
entityTypeBuilder
.HasIndex(i => new i.Name, i.Category.Id )
.IsUnique();
但是由于Category.Id
导航属性,当我生成迁移时这会失败。
我知道我可以将值硬编码为字符串,但我不想丢失静态类型。
我有什么选择?
【问题讨论】:
【参考方案1】:只要知道影子属性名称,就可以使用(至少在 EF Core 1.1.0 中)基于字符串的HasIndex
方法overload
public virtual IndexBuilder HasIndex(params string[] propertyNames)
例如
entityTypeBuilder
.HasIndex("Name", "CategoryId")
.IsUnique();
HasAlternateKey
也一样:
entityTypeBuilder
.HasAlternateKey("Name", "CategoryId");
【讨论】:
是的,这就是我现在正在做的事情,正如我在问题中所说,你失去了静态类型。也许这是唯一的方法。 对于谁在阅读。您不会丢失静态类型。只需使用 nameof(Type.Property) 虽然失去了“”括号。 entityTypeBuilder.HasIndex("Name", "CategoryId").IsUnique(); @BenVertonghen 谢谢,已修复。【参考方案2】:在相关实体上为类别 CategoryId
添加外键,并在索引构建器中使用它而不是导航属性。
【讨论】:
是的,但这很乱。这是唯一的选择吗? 你为什么认为这很乱?添加外键属性并不混乱,你为什么这么认为? @grokky @grokky - 我认为不定义外键属性很麻烦。 EF docs recommend it,而且,我宁愿不引入影子属性。 @kizilsu 它将与基础设施相关的属性添加到与域相关的类中。很乱。我不喜欢它,但似乎这是唯一可用的选项,而不是放弃静态类型。 @kizilsu 不,我不会那样做。但是 ORM 的重点是与数据库的工作相隔离。有时这是不可能的,比如这种情况。【参考方案3】:作为对伊万出色回应的延伸:
如果你预先定义了外键,你至少可以控制名称关联
const string auditForeignKey = "AuditId";
builder.HasOne(e => e.Audit)
.WithMany(e => e.AuditLocations)
.HasForeignKey(auditForeignKey);
builder.HasIndex(auditForeignKey, nameof(AuditLocation.LocationId)).IsUnique();
【讨论】:
以上是关于在 EF Core 中生成复合唯一约束/索引的主要内容,如果未能解决你的问题,请参考以下文章