【问题标题】:How do you add a unique constraint on multiple navigation properties in Entity Framework?如何在 Entity Framework 中为多个导航属性添加唯一约束?
【发布时间】:2015-07-13 07:13:26
【问题描述】:

我有以下实体,它为我提供了一个自动递增的 PK、两列(或用 EF 行话“关系”)和一个布尔值。它按预期工作。

public class SomeEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SomeID { get; set; }
    public virtual UserAttribute UserAttribute { get; set; }
    public virtual User User { get; set; }
    public bool Value { get; set; } 
}

现在我想添加一个约束,以便 UserAttributeUser 的组合必须是唯一的。这代替了使它们成为复合主键。所以我添加了一些注释,它看起来像这样:

public class SomeEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SomeID { get; set; }
    [Index("IX_MyTwoColumns", 1, IsUnique = true)]
    public virtual UserAttribute UserAttribute { get; set; }
    [Index("IX_MyTwoColumns", 2, IsUnique = true)]
    public virtual User User { get; set; }
    public bool Value { get; set; } 
}

当我在 Management Studio 中查看索引时,我看不到 IX_MyTwoColumns。怀疑这与使用关系有关,我添加了两个虚拟列 foobar 并指定了一个唯一的多列索引:

public class SomeEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SomeID { get; set; }
    [Index("IX_MyTwoColumns", 1, IsUnique = true)]
    public virtual UserAttribute UserAttribute { get; set; }
    [Index("IX_MyTwoColumns", 2, IsUnique = true)]
    public virtual User User { get; set; }

    [Index("IX_FooAndBar", 1, IsUnique = true)]
    public int Foo { get; set; }
    [Index("IX_FooAndBar", 2, IsUnique = true)]
    public int Bar { get; set; }

    public bool Value { get; set; } 
}

IX_FooAndBar 出现在设计器中,确实表明这两列是唯一索引的一部分。

我做错了什么?看来我正在为 UserUserAttribute 设置 FK,但我不知道如何确保它们的组合是唯一的。

【问题讨论】:

    标签: sql-server entity-framework indexing


    【解决方案1】:

    使用数据注释,您需要在关系的列上插入索引。

    public class SomeEntity
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int SomeID { get; set; }
        [Index("IX_MyTwoColumns", 1, IsUnique = true)]
        public int UserAttributeId { get; set; }
        [ForeignKey("UserAttributeId")]
        public virtual UserAttribute UserAttribute { get; set; }
    
        [Index("IX_MyTwoColumns", 2, IsUnique = true)]
        public int UserId {get; set;}
        [ForeignKey("UserId")]
        public virtual User User { get; set; }
        public bool Value { get; set; } 
    }    
    

    【讨论】:

    • 这是某种 EF 幕后魔法吗? EF 如何知道那些 ID 列属于 Reltionship?如果这两个表都使用“ID”而不是 XXXID,我想它不会起作用?
    • :) 在这种情况下是导航属性之前的 ForeignKeyAttribute。在 UserId 属性上,您还可以使用 Column 属性。
    • 有趣的是,在您回复之前,我尝试添加了 UserID 和 UserAttributeID 并且成功了!虽然我没有包含 [ForeignKey("XXX")] 注释。 ER 图和索引看起来是一样的。这个注释真的有必要吗?当某些东西有效时我讨厌它,我怀疑它不应该!
    • 经过一些实验,我发现它不是必需的,但是如果您希望 CASCADE DELETE 工作(并且不必在 OnModelCreating 中使用流利的)它是必需的。听起来对吗?如果是这样,您只是用一块石头杀死了两只鸟!
    • 我对使用 ForeignKey 时的级联是否正确?从老板那里得到一些压力来完成这件事。 :)
    猜你喜欢
    • 1970-01-01
    • 2019-04-19
    • 2017-05-05
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多