实体框架 - 独特索引上的UPSERT

时间:2014-11-20 20:55:33

标签: c# sql entity-framework upsert

我对我的问题进行了一些搜索,但找不到任何真正有用的东西。

所以我的问题/困境保持如下: 我知道mysql数据库有一个唯一的索引系统,可以使用这种格式在同一查询中插入/更新: insert into t(a,b,c) values(1,1,1) on duplicate keys update b=values(b),c=values(c); 以及用于替换该索引的现有记录的替换格式。

老实说,我在MSSQL中看到的唯一类似的东西是merge,但我真的不喜欢它,并且验证插入或更新的查询根本不是唯一的索引。

那么如何将mysql独特的UPSERT模拟到Entity Framework中呢?这是我的主要问题......

我的意思是没有从实体集中获取记录并检查它是否为空或者是否为可能的插入或更新;

我可以得到它吗?或不?任何提示都很有用

我看到this但未出现在版本6中...

实体的例子:

    [Table("boats")]
    public class Boat
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int id { get; set; }
        [MaxLength(15)]
        [Index("IX_ProviderBoat",1,IsUnique=true)]
        public string provider_code { get; set; }
        public string name { get; set; }
        [Index("IX_ProviderBoat", 3, IsUnique = true)]
        [MaxLength(50)]
        public string model { get; set; }
        [Index("IX_ProviderBoat", 2, IsUnique = true)]
        [MaxLength(15)]
        [Key]
        public string boat_code { get; set; }
        public string type { get; set; }
        public int built { get; set; }
        public int length { get; set; }            
    }

所以我想使用EF

基于我的IX_ProviderBoat唯一索引更新/插入

enter image description here

1 个答案:

答案 0 :(得分:19)

AddOrUpdate方法是IDBSet的成员,可在EF6中使用。

AddOrUpdate方法不是原子操作,来自多个线程的调用不保证第二个线程Update而不是Add再次 - 所以你可以获得重复记录存储

此示例经过测试并符合您的期望:

        Boat boat = new Boat // nullable fields omitted for brevity 
        {
            boat_code = "HelloWorld",
            id = 1,
            name = "Fast Boat",
            built = 1,
            length = 100
        };

        using (BoatContext context = new BoatContext()) // or whatever your context is
        {
            context.Set<Boat>().AddOrUpdate(boat); // <-- IDBSet!!!
            context.SaveChanges();
        }

如果我们更改boat_codeAddOrUpdate()方法将添加新记录。如果boat_code是'HelloWorld`,它将更新现有记录。我相信这就是你要找的......

希望这有帮助!