what is the Alternate for AddorUpdate method in EF Core?

11,898

Solution 1

Simply use

context.Update(entity);

It does exactly AddOrUpdate based on value of entity PrimaryKey (0 means Add, > 0 means Update):

public virtual void AddOrUpdate(T entity)
{
    if (entity == null)
        throw new ArgumentNullException("entity");

     this.DbContext.Update(entity);  
     this.DbContext.SaveChanges();
}

Solution 2

If you work with composite keys you can use next method I wrote:

public static void AddOrUpdateRange<TEntity>(this DbSet<TEntity> set, IEnumerable<TEntity> entities)
            where TEntity : class
        {
            foreach (var entity in entities)
            {
                _ = !set.Any(e => e == entity) ? set.Add(entity) : set.Update(entity);
            }
        }
Share:
11,898
Naurto san
Author by

Naurto san

Updated on June 03, 2022

Comments

  • Naurto san
    Naurto san almost 2 years

    I want to achieve the ADDorUpdate() method in Generic repository using EF Core like below? Can anyone help me?

      public virtual void AddOrUpdate(T entity)
        {
            #region Argument Validation
    
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            #endregion
             DbSet.AddOrUpdate(e => e.Id, entity);  
            this.DbContext.SaveChanges();
        }
    
  • Naurto san
    Naurto san almost 4 years
    Hi Bolkey, getting an error as "Operator == cannot be applied to operends of type 'Tkey ' and T'key'"
  • Naurto san
    Naurto san almost 4 years
    Hi Arman, I have found the same in Microsoft docs. But read an article in the internet as it's not gonna solve. Is it?
  • Arman Ebrahimpour
    Arman Ebrahimpour almost 4 years
    @Naurtosan Behavior of Update in EF Core 3 is what I said and it will work
  • Naurto san
    Naurto san almost 4 years
    Thanks, @Arman. I will check this. AndI have a small confusion, in my class, we have declared dbonctext and dbset . And in my constructor, we are setting like this.DbContext = dbContext; this.DbSet = this.DbContext.Set<T>(); So my question is can I set like Dbset.Update(entity); instead of this.DbContext.Update(entity); . in my method. Can you please give reply ?
  • Arman Ebrahimpour
    Arman Ebrahimpour almost 4 years
    @Naurtosan Yes you can. Both of them do the same thing
  • Naurto san
    Naurto san almost 4 years
    Thanks for the reply @Bolkay. Please find the link for IGenricRepo and GNericRepo c-sharpcorner.com/forums/…
  • perustaja
    perustaja over 3 years
    See docs.microsoft.com/en-us/ef/core/saving/… the primary key issue was not causing this to work for me.
  • kewur
    kewur about 3 years
    does this actually work for anyone? I'm using EF 3,1, when trying to update a non existent entry I'm getting this exception " Data may have been modified or deleted since entities were loaded."
  • fr332lanc3
    fr332lanc3 about 3 years
    What about when you aren't tracking entities though and you have a dup key conflict? An efficient raw SQL/MySQL query method is to "ON DUPLICATE KEY UPDATE" when a constraint is violated on a query and then update the instead. Otherwise you have dup queries to query a row to see if it exists then deciding to add or update it in your code, its less efficient and won't scale well where the other way does directly with the database engine you give it the data, it decides how to handle it with one query and less of a performance penalty. And in your code you may not know yet if its a dup...
  • Poul Bak
    Poul Bak almost 3 years
    NOTE: This only works for AUTOGENERATED keys, otherwise you will get ConcurrencyException
  • maxc137
    maxc137 almost 3 years
    This will send request to DB for every entity. Also all calls to DB should be async (use AnyAsync in your case).
  • Koen van der Linden
    Koen van der Linden over 2 years
    @МаксимКошевой the Add() or Update() will only change the local data. Only when calling SaveChange() will interact with database.
  • maxc137
    maxc137 over 2 years
    @Koen van der Linden I'm talking about set.Any. It will send a request to db for every entity.