【问题标题】:Create Unique constraint for 'true' only in EF Core仅在 EF Core 中为“true”创建唯一约束
【发布时间】:2018-10-08 17:08:06
【问题描述】:

我有一个跟踪记录附件的类。每个 Record 可以有多个 RecordAttachment,但要求每个 Record 只能有一个 RecordAttachment,标记为IsPrimary

public class RecordAttachment
{
    public int Id { get; set; }
    public int RecordId { get; set; }
    public string Details { get; set; }
    public bool IsPrimary { get; set; }

    public Record Record { get; set; }
}

我不能只使用.HasIndex(e => new { e.RecordId, e.IsPrimary }).IsUnique(true),因为每个记录可以有多个false 值。

基本上我需要对RecordIdIsPrimary == true 进行唯一约束,尽管这不起作用:

entity.HasIndex(e => new { e.RecordId, IsPrimary = (e.IsPrimary == true) }).IsUnique(true)

编辑: 查看这样的答案:Unique Constraint for Bit Column Allowing Only 1 True (1) Value 似乎可以直接使用 SQL 创建约束,但它不会反映在我的模型中。

【问题讨论】:

  • 听起来Record 应该有一个主要的RecordAttachment 和许多非主要的RecordAttachments,而不是有IsPrimary 列。所以基本上是一对一的关系,然后是一对多的关系。
  • 另一种选择是将IsPrimary 替换为整数列,其中 1 表示主要值,您只需将所有其他值设置为唯一值。
  • @juharr 如果无法做到这一点,这将是一个选项,将PrimaryAttachmentId 添加到Record 并单独处理。

标签: c# sql-server entity-framework-core


【解决方案1】:

您可以使用HasFilter fluent API 指定索引过滤器。

不幸的是,它与数据库无关,因此您必须使用目标数据库 SQL 语法和实际的表列名。

对于 Sql Server,它会是这样的:

.HasIndex(e => new { e.RecordId, e.IsPrimary })
.IsUnique()
.HasFilter("[IsPrimary] = 1");

    .HasIndex(e => new { e.RecordId, e.IsPrimary })
    .IsUnique()
    .HasFilter($"[{nameof(RecordAttachment.IsPrimary)}] = 1");

有关详细信息,请参阅Relational Database Modeling - Indexes 文档主题。

【讨论】:

  • 优秀。我唯一的抱怨是使用字符串会阻止它在属性被重命名时自动更改,但是哦,好吧。
  • @Valuator 为此,您可以使用nameof
  • 使用 nameof 的示例:.HasIndex(e => new { e.RecordId, e.IsPrimary }).IsUnique().HasFilter($"[{nameof(RecordAttachment.IsPrimary)}] = 1 ");
  • 我有一个问题,当我使用这个时。我也不允许插入 isPrimary = false 的条目。还会抛出 duplicateEntry 异常。
  • 嘿@ivan stoev 发现这是 2018 年报告的 mariadb 错误。mariadb 忽略条件索引或部分索引。
猜你喜欢
  • 2020-10-12
  • 2018-09-14
  • 1970-01-01
  • 2017-04-07
  • 2022-01-23
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 2022-11-19
相关资源
最近更新 更多