2013-04-24 55 views
10

我想插入現有實體的引用成員。是否必須手動完成EF upsert?

我是否必須爲upsert編寫特定的代碼?

含義:我必須檢查是否處理現有的引用成員或新的引用成員。

有沒有其他簡單的方法來做到這一點?

當你只做Save會發生什麼?

public void SaveCofiguration(MamConfiguration_V1Ui itemUi) 
     { 
      var itemEf = mMamConfiguration_V1UiToEfConvertor.ConvertToNewEf(itemUi); 

      using (var maMDBEntities = new MaMDBEntities()) 
      { 
       IDal<MamConfiguration_V1> mamConfigurationDal = mDalFactory.GetDal<MamConfiguration_V1>(maMDBEntities); 

       mamConfigurationDal.Save(itemEf); 
      } 
     } 

     public MamConfiguration_V1 GetById(object id) 
     {   
       id.ThrowIfNull("id"); 

       int configurationId = Convert.ToInt32(id); 

       var result = 
        mMaMDBEntities.MamConfiguration_V1.SingleOrDefault(item => item.ConfigurationId == configurationId); 

       return result; 

     } 

     public MamConfiguration_V1 Save(MamConfiguration_V1 item) 
     { 

       item.ThrowIfNull("item"); 

       var itemFromDB = GetById(item.ConfigurationId); 

       if (itemFromDB != null) 
       { 
        UpdateEfItem(itemFromDB, item); 

        // if (mMaMDBEntities.ObjectStateManager.GetObjectStateEntry(itemFromDB).State == EntityState.Detached) 
//     { 
    //      mMaMDBEntities.MamConfiguration_V1.AddObject(itemFromDB); 
    //    } 

        // Attached object tracks modifications automatically 
        mMaMDBEntities.SaveChanges(); 

        return item; 
       } 





     private void UpdateEfItem(MamConfiguration_V1 itemFromDb, MamConfiguration_V1 itemFromUi) 
      { 
       itemFromDb.UpdatedDate = DateTime.Now; 

       itemFromDb.Description = itemFromUi.Description; 

       itemFromDb.StatusId = itemFromUi.StatusId; 

       itemFromDb.Name = itemFromUi.Name; 

       itemFromDb.NumericTraffic = itemFromUi.NumericTraffic; 

       itemFromDb.PercentageTraffic = itemFromUi.PercentageTraffic; 

       itemFromDb.Type = itemFromUi.NumericTraffic; 

       foreach (var item in itemFromDb.MamConfigurationToBrowser_V1.ToList()) 
       { 
        if (itemFromUi.MamConfigurationToBrowser_V1.All(b => b.BrowserVersionId != item.BrowserVersionId)) 
        { 
         mMaMDBEntities.MamConfigurationToBrowser_V1.DeleteObject(item); 
        } 
       } 

       for (int i = 0; i < itemFromUi.MamConfigurationToBrowser_V1.Count; i++) 
       { 
        var element = itemFromUi.MamConfigurationToBrowser_V1.ElementAt(i); 
        var item = itemFromDb.MamConfigurationToBrowser_V1.SingleOrDefault(b => b.BrowserVersionId == element.BrowserVersionId); 
        if (item != null) 
        { 
         // copy properties from element to item 
        } 
        else 
        { 
         element.Browser = mMaMDBEntities.Browsers.Single(browserItem => 
          browserItem.BrowserID == element.BrowserID); 

         //element.MamConfiguration_V1 = itemFromDb; 

         //have also tried: element.MamConfiguration_V1 = null; 

         //element.MamConfiguration_V1Reference = null; 

         itemFromDb.MamConfigurationToBrowser_V1.Add(element); 
        } 
       } 
      } 

但我會教人口會Save(itemUi)SaveChanges()做工精細。沒有?

+0

一種選擇是使用一個唯一的索引和執行插入:'DbUtils.IgnoreErrors(_db,()=> DbUtils.InsertEntity(_db,someEntity) DbUtils.IsDuplicateInsertError);'從:http://stackoverflow.com/questions/19042107/handle-exceptions-in-entity-framework-4/34670770#34670770 – 2016-10-13 02:19:04

回答

18
public void InsertOrUpdate(DbContext context, UEntity entity) 
{ 
    context.Entry(entity).State = entity.Id == 0 ? 
            EntityState.Added : 
            EntityState.Modified; 
    context.SaveChanges(); 
} 

http://forums.asp.net/t/1889944.aspx/1

+0

當你只做「保存」時會發生什麼? – 2013-04-25 15:38:38

+0

我正在處理導航成員的upsert。那該怎麼做? – 2013-04-26 20:18:33

+0

當您構造整個實體時 - 通過它的主鍵(可能是複合) - 然後想要更新該行(如果它已經存在於數據庫中)或者想要添加它如果沒有。 AddOrUpdate方法更好。 – AyCabron 2017-09-21 00:36:32

3

參見 'AddOrUpdate' System.Data.Entity.Migrations的方法。
http://msdn.microsoft.com/en-us/library/system.data.entity.migrations.idbsetextensions.addorupdate%28v=vs.103%29.aspx

using System.Data.Entity.Migrations; 

public void Save(Person person) { 
    var db = new MyDbContext(); 
    db.People.AddOrUpdate(person); 
    db.SaveChanges(); 
} 
+5

我建議在正常的數據庫使用期間不要使用AddOrUpdate。此方法僅用於播種數據庫,請參閱[Julie Lerman的文章](http://thedatafarm.com/data-access/take-care-with-ef-4-3-addorupdate-method/)以獲取進一步解釋。 – Nick 2015-02-07 00:00:31

+2

@尼克這篇文章說得很好。但是,如果開發人員知道AddOrUpdate不能用於只更新一個屬性而沒有完整的原始對象來保存其他屬性,那麼我想知道爲什麼不呢?如果你只有主鍵並且想要忍者(只改變)一個或兩個屬性,那麼需要以不同的方式進行編碼。至於我對Elad的回答,方法文檔確實表示「等同於數據庫術語的'upsert'操作。」 – jaybro 2015-02-12 15:47:21

+0

顯然它受到競爭條件的影響,因爲它正在做選擇以查找實體是否存在。 – 2015-04-17 09:37:33

相關問題