Does EF upsert have to be done manually?

c#, entity-framework, sql

Solution

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

Problem

I want to upsert reference members of an existing entity. Do I have to write specific code for the upsert? meaning: I have to check if I'm handling an existing reference member or a new one. Is there any other simple way to do so? What happens when you do only `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); } } } ``` But I would have expecte `Save(itemUi)` and `SaveChanges()` to work fine. No?

Original source

Related problems