【问题标题】:EF CodeFirst Validation of Unique composite keyEF CodeFirst 验证唯一复合键
【发布时间】:2012-06-29 14:05:47
【问题描述】:

我有一个包含 Id 列作为主键的表。还需要在其他两个列上强制唯一性,这两个列实际上是 FK。在 Sql Server 中,我可以在这两列上创建一个 UniqueKey。

我可以在 EF 端做什么,以便它可以验证这两个字段的唯一性?

【问题讨论】:

    标签: entity-framework entity-framework-4 ef-code-first data-annotations


    【解决方案1】:

    EF 不支持唯一键,因此您最好的解决方法是在数据库中使用唯一键并在保存期间捕获异常。如果您需要 EF 在创建数据库期间创建唯一键,您可以use custom initializer

    如果您想在应用程序中进行一些验证,您将需要执行一些查询并检查这些数据是否尚不存在,但您仍然需要使用前一个通知来捕获异常,因为另一个线程/进程/用户可以在查询和保存更改之间创建此类数据。

    【讨论】:

    • 您好,在发布此问题之前,我已经查看了您链接到的帖子。执行一些查询是什么意思?我在这里看到两个可能的问题:1)我需要将新值与数据库中的现有值进行比较,以及 2)我在内存数据中有重复值,因此第二条记录的插入/更新将失败。您认为 DataAnnotations 在这种情况下不适用吗?
    • 数据注释不适用,因为您可以在不同的上下文实例中在内存中具有相同的值。在这种情况下,数据注释的验证将通过,但真正的验证只会发生在数据库中。
    【解决方案2】:

    在您的 POCO 类中,将需要唯一的每一列标记为 Key。如:

    public MyPocoClass {
       [Key, Column(Order = 0)]
       public int Id { get; set; }
    
       [Key, Column(Order = 1)]
       public int Col2name { get; set; }
    
    
       [Key, Column(Order = 2)]
       public int Col3name { get; set; }
    }
    

    设置列顺序很有用,这样您的主键列都会一起显示在 sql db 中。

    如果这些列是其他实体框架代码第一类的外键,则只需将该属性命名为 tablename_tableId,其余的将由 EF 完成。即

    public anotherClass {
           public int Id { get; set; }
    
           public int MyPocoClass_Id { get; set; } //this is a foreign key
    
        }
    

    【讨论】:

    • 您的意思是:EF 将完成剩下的工作?我认为你误解了我的问题。如何在客户端检查是否有两条 Col2Name 和 Col3Name 值相同的记录?
    • 实体框架将涵盖外键的验证,如果您尝试插入不唯一的行或外键不作为键存在,上下文将抛出异常桌子。这有帮助吗?
    • 不。如果我到达对数据库执行 QUERY 的地步,这意味着 EF 根本没有处理验证。我的问题是:我可以在 EF/客户端做些什么来验证数据。
    • 我不确定您要达到的目标。无论您选择哪种方式,您都必须与数据库联系。要检查主键/外键是否有效,您需要知道数据库表包含的内容。如果你想将表加载为一个集合,然后遍历它以检查键的验证,你可以,但你仍然需要访问数据。
    • 我不是要验证 FK 是否有效,而是要结合两个属性的值来验证值的唯一性。就我而言,这两个属性是 FK,但不一定总是如此。如果你到了引发异常的地步,验证永远不会发生。此链接blogs.microsoft.co.il/blogs/shimmy/archive/2012/01/23/… 谈到基于属性的验证,我对实体级别的唯一性验证感兴趣。
    猜你喜欢
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 2020-04-24
    • 2013-12-10
    • 2015-10-15
    • 2021-09-16
    • 2015-05-19
    • 1970-01-01
    相关资源
    最近更新 更多