How to Bulk Update records in Entity Framework?

前端 未结 7 2205
遥遥无期
遥遥无期 2020-12-01 08:00

I am trying to bulk update records using Entity Framework. I have tried Entity Framework.Extensions Update method.

The Update method is abl

7条回答
  •  被撕碎了的回忆
    2020-12-01 08:41

    I found an easy way to do that without any 3rd party packages:
    By adding one generic extension method SetValue you can simply write:

    Example:

    void Main()
    {
        
        var dc = this; // context
        var p = dc.Purchases.Where(x=>x.Description.ToLower()=="bike")
                            .SetValue(w => w.Description = "Bicycle");
        p.Dump();
        dc.SubmitChanges();
    }
    

    As you can see, any value matching the Where condition can be set explicitly to a new value, so here Bike will be replaced by Bicycle. You can query the table afterwards to see the changes really persisted.

    Of course, you could also omit the Where statement, if you want to change all records like:

    dc.Records.SetValue(x => x.Quantity = 100);
    dc.SubmitChanges();
    

    Entity framework (EF) / LINQ tracks those changes and when you call .SubmitChanges() - as you can see in the SQL tab if you're using LinqPad - it will create SQL code as follows:

    -- Region Parameters
    DECLARE @p0 Int = 3
    DECLARE @p1 VarChar(1000) = 'Bicycle'
    -- EndRegion
    UPDATE [Purchase]
    SET [Description] = @p1
    WHERE [ID] = @p0
    

    For small changes, this is ok, but for large tables it is becoming inefficient, because it uses the ID column to identify and change a record, and not the Description column as defined by .SetValue.

    Theoretically EF could optimize this, but as you can see, it doesn't do it. So if you want true bulk operations you need to run a SQL command instead or create a stored procedure (for complex queries) which you're calling via EF.


    Extension method SetValue

    This extension method does the trick (no other 3rd party packages required):

    // see: https://visualstudiomagazine.com/articles/2019/07/01/updating-linq.aspx
    public static class Extensions
    {
        public static IEnumerable SetValue(this IEnumerable items, 
                                                      Action updateMethod)
        {
            foreach (T item in items)
            {
                updateMethod(item);
            }
            return items;
        }
    }
    

    Note: The example above uses the Nutshell example database, which you can easily create by following this link and the code is written for LinqPad 6 but can be adapted easily (LinqPad 6 uses .NET Core, but you can try it with LinqPad 5 as well for the .NET Framework).

提交回复
热议问题