Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does EF upsert have to be done manually?

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?

like image 524
Elad Benda Avatar asked Apr 24 '13 15:04

Elad Benda


People also ask

How do I update my EF record?

We can update records either in connected or disconnected scenarios. In the connected Scenario, we open the context, query for the entity, edit it, and call the SaveChanges method. In the Disconnected scenario, we already have the entity with use. Hence all we need to is to attach/add it to the context.

What is Upsert operation?

The term upsert is a portmanteau – a combination of the words “update” and “insert.” In the context of relational databases, an upsert is a database operation that will update an existing row if a specified value already exists in a table, and insert a new row if the specified value doesn't already exist.

How do I update entity in Efcore?

To update an entity with Entity Framework Core, this is the logical process: Create instance for DbContext class. Retrieve entity by key. Make changes on entity's properties.


2 Answers

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

like image 194
Robert Harvey Avatar answered Sep 18 '22 11:09

Robert Harvey


To avoid the overhead of a query and then insert, or throwing exceptions, you can take advantage of the underlying database support for merges or upserts.

This nuget package does the job pretty well: https://www.nuget.org/packages/FlexLabs.EntityFrameworkCore.Upsert/

Github: https://github.com/artiomchi/FlexLabs.Upsert

Example:

DataContext.DailyVisits     .Upsert(new DailyVisit     {         // new entity path         UserID = userID,         Date = DateTime.UtcNow.Date,         Visits = 1,     })     // duplicate checking fields     .On(v => new { v.UserID, v.Date })     .WhenMatched((old, @new) => new DailyVisit     {         // merge / upsert path         Visits = old.Visits + 1,     })     .RunAsync(); 

The underlying generated sql does a proper upsert. This command runs right away and does not use change tracking, so that is one limitation.

like image 20
jjxtra Avatar answered Sep 19 '22 11:09

jjxtra