实体框架错误地跨多个列强制执行唯一约束

时间:2017-04-07 20:00:53

标签: c# sql .net entity-framework ef-code-first

编辑:我很抱歉浪费了你的时间。调试导致此问题时,我错过了一行代码。有人提出了一个条件,即检查数据库中是否已存在该名称,如果存在,则抛出此异常。

我首先使用实体​​框架代码,我有一个实体,其中包含一个跨两列的唯一约束的索引,如下面的代码所示。 (我将属性的名称更改为通用的东西,以便不显示我公司的任何代码库)

[Table("TB_Table")]
public class Table : IEntity
{
    [Key]
    [Column("TBT_RID")]
    public int Id { get; set; }

    [ForeignKey("Something")]
    [Index("idxSomethingTableName", 1, IsUnique = true)]
    [Column("TBT_SOS_RID")]
    public int SomethingId { get; set; }

    [Index("idxSomethingTableName", 2, IsUnique = true)]
    [MaxLength(255)]
    [Column("TBT_Name")]
    public string Name { get; set; }

    // Navigation properties
    [JsonIgnore]
    public virtual Something Something { get; set; }

    [InverseProperty("Table")]
    [JsonIgnore]
    public virtual ICollection<AssetTag> ObjectTables { get; set; }

}

在SQL中插入记录时,正在强制执行唯一约束。然后,当尝试通过实体框架输入记录时,它告诉我它不能添加具有不同“SomethingId”值的记录,但是与另一个记录具有相同的“名称”。

例如,我可以使用SQL插入这些记录:

insert into TB_Table (TBT_SOS_RID, TGT_Name) values
(1, 'A'),
(1, 'B'),
(30, 'A')

但是我不能用SQL添加另一个(1,'A')。好,太棒了。约束正常工作。现在,如果我尝试使用具有值(30,'B')的实体框架插入记录,我应该能够这样做,因为TBT_SOS_RID(C#中的SomethingId)是不同的。相反,我得到一个InvalidOperationException,消息“无效表,表已存在”。在调用SaveChanges()方法之前,会在DbSet.Add()方法上发生这种情况。

你能想到为什么实体框架会认为这是违反SQL时没有的唯一约束的原因吗?

2 个答案:

答案 0 :(得分:3)

Kryptos似乎回答了关于如何使用外键处理复合索引的类似问题:Composite Indices with Foreign Keys

我没有测试过该解决方案,但它可能会帮助您走上正确的道路,在同一问题中扩展answer by niaher

答案 1 :(得分:0)

你装饰名字如下:

[Index("idxSomethingTableName", 2, IsUnique = true)]
[MaxLength(255)]
[Column("TBT_Name")]
public string Name { get; set; }

就实体而言,您已声明Name必须是唯一的,因此,您不能输入两个相同的名称。