【问题标题】:Entity Framework: Indexing a child entity based on a value on the parent entity for uniqueness实体框架:根据父实体上的值对子实体进行索引以实现唯一性
【发布时间】:2019-11-19 07:30:29
【问题描述】:

我有一个简短的问题,正在寻找最好的方法来做到这一点,不知道 EF 是否有能力?我正在使用 EntityFramework 6.3。

我有以下父子场景,

public class Application{
 [Key]
 public int ApplicationId {get;set;}
 public string Name {get;set;}
 public string Status {get;set;}

 public virtual List<Document> Documents {get;set;}
}

public class Document{
 [Key]
 public int DocumentId {get;set;}
 [Index("IX_ApplicationDocument", 1, IsUnique = true)]
 public string DocumentType {get;set;}
 [Index("IX_ApplicationDocument", 1, IsUnique = true)]
 public string Name {get;set;}

 public int ApplicationId {get;set;}

 [ForeignKey("ApplicationId")]
 public Application Application {get;set;}
}

所以向一个部门提出申请,并存储在数据库中,每个申请都有一个状态,提交时,状态为待处理,因为在批准之前必须进行各种验证。当申请被拒绝时,提交者必须提出新的申请(请注意,我使用了一个比实际情况更简单的示例),但是,申请人可以再次提交相同的文件。问题是,这已经存在于系统中,无法复制。如您所见,他们第二次尝试提交时会抛出约束异常。如何使用 EF 克服这个问题,有没有办法根据父母的状态创建约束,或者这只能以编程方式完成?

【问题讨论】:

  • 你能澄清一下吗,你希望 documentId 在未来是唯一的,但对现有的来说可以重复吗?
  • 基本上,如果您想避免新条目重复,则可以使用实体框架在 SQL Server 上创建过滤的唯一索引。如果是这种情况,请告诉我

标签: c# entity-framework-6 data-annotations entity-relationship unique-constraint


【解决方案1】:

不知道它是否对你有帮助,但看看这个

假设你的实体被定义为

public class Entity
{
    public int Id { get; set; }
    public int Parent { get; set; }
    public int Child { get; set; }
}

遵循流畅的 API 代码将根据需要创建索引:

modelBuilder.Entity<Entity>().HasIndex(p => new {p.Parent, p.Child})
        .HasFilter("isdeleted = 0")
        .HasName("unq_t_parent_child");

SQL 生成

CREATE INDEX [unq_t_parent_child] ON [Entity] ([Parent], [Child]) WHERE isdeleted = 0;

HasIndex 定义表 Entity 中属性的索引

HasFilter 允许您为索引设置过滤器。此值为 sql,因此您需要确保编写正确的 sql 语法。

HasName 配置索引的名称。

(如果您将实体映射到表 t 并将属性映射到它们的列名,迁移将创建与您想要的完全相同的 sql。)

检查约束也不同于唯一索引。如果您要添加检查约束,则需要在迁移文件中使用 migrationBuilder.Sql。

【讨论】:

  • 哦,天哪,正是我一直在寻找的东西,我知道您可以在 Oracle 中做到这一点,只是从编码的角度不确定如何做到这一点。非常感谢@Syed_Wahhab。这让我大开眼界:-)
  • 一个问题,被删除,这是实体的属性还是保留字?
  • No donny 'isdeleted' 不是 EF 的属性。
  • 不幸的是,此解决方案适用于 EntityFramework Core,并且确实指定了我正在使用的版本 :-( 我使用的是 EntityFramework 6.3。
【解决方案2】:

所以很遗憾,我已经四处搜索,但没有针对 EF 6 的解决方案。我可以做到这一点的最佳方法是遵循以下文章的指导,您可以在创建表后在迁移中手动添加过滤索引。

Blog

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 2016-07-01
    • 2013-05-24
    • 2019-04-13
    • 1970-01-01
    相关资源
    最近更新 更多