簡體   English   中英

實體框架(EF6)插入或更新(如果存在)屬性

[英]Entity Framework (EF6) insert or update if exists for properties

假設模型如下:

class Foo {
    virtual Bar Bar {get; set ;}
}

class Bar {
    int Id { get; set; }
    string Property {get; set;}
}

class MyContext {
     virtual DbSet<Foo> Foos {get; set;}

    void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<Bar>()
            .HasKey(c => c.Property);
    }
}

和一些類似的代碼:

void DoStuff() {
   var foos = GetFoosFromExternalSource();

   using(var ctx = new MyContext() {
       foreach(var foo in foos) {
            ctx.Foos.Add(foo);
       }

       ctx.SaveChanges();
   }
}

IEnumerable<Foo> GetFoosFromExternalSource() {
     yield return new Foo {
          Bar = new Bar { Id = 1, Property = "Hello" }          
     };
     yield return new Foo {
          Bar = new Bar { Id = 2, Property = "World" }          
     };
     yield return new Foo {
          Bar = new Bar { Id = 1, Property = "Hello" }          
     }    
}

這將引發異常:

違反主鍵約束'PK_dbo.Bar'。 無法在對象“ dbo.Bar”中插入重復鍵。 重復的鍵值為(Hello)。

我如何向EF明確指出,如果Bar對象具有相同的Key(或Id,或兩者),則它被視為同一實例?

我知道如果我能做些類似的事情

 IEnumerable<Foo> GetFoosFromExternalSource() {
     var bar1 = new Bar { Id = 1, Property = "Hello" };
     var bar2 = new Bar { Id = 2, Property = "World" };

     yield return new Foo {
          Bar = bar1          
     };
     yield return new Foo {
          Bar = bar2         
     };
     yield return new Foo {
          Bar = bar1
     }    
}

會很好的。 但是,由於這是來自外部源的數據,因此這是不可能直接實現的。 我的真實場景具有多個級別和許多屬性。 所以我想在模型中解決這個問題。

而不是添加實體,您應該使用“ upsert”庫(或創建自己的庫)。 例如, FlexLabs.Upsert就是這樣的Entity Framework Core庫。

在您的情況下,代碼將如下所示(基於docu):

async Task DoStuff()
{
   var foos = GetFoosFromExternalSource();
   using(var ctx = new MyContext()
   {
       await ctx.Foos
           .UpsertRange(foos)
           .On(f => f.Property)
           .RunAsync();
       ctx.SaveChanges(); // not sure if savechanges call is necessary based on docu...
   }
}

注意:我以前沒有使用過FlexLabs.Upsert前段時間有朋友向我推薦了它,還沒有時間對其進行進一步的試驗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM