【问题标题】:Generate a composite unique constraint/index, in EF Core在 EF Core 中生成复合唯一约束/索引
【发布时间】:2017-04-07 16:05:06
【问题描述】:

我需要为我的实体的 Name 属性设置一个复合唯一约束,该约束在 Category 中是唯一的(它有一个 FK)。

所以是这样的:

entityTypeBuilder
  .HasIndex(i => new { i.Name, i.Category.Id })
  .IsUnique();

但是由于Category.Id 导航属性,当我生成迁移时这会失败。

我知道我可以将值硬编码为字符串,但我不想丢失静态类型。

我有什么选择?

【问题讨论】:

    标签: entity-framework entity-framework-core entity-framework-migrations ef-fluent-api


    【解决方案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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-28
      • 2017-09-15
      • 1970-01-01
      • 2018-10-08
      • 2018-09-14
      • 1970-01-01
      • 2015-12-29
      • 2011-03-18
      相关资源
      最近更新 更多