Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework: Update inside LINQ query

I've came across this idea of updating a table inside of a LINQ query instead of making the query first, and updating each object returned by that query.

For instance, it is possible to change the value of any property associated with x inside of this query:

var Query = from x in EFContext.SomeTable
            where x.id == 1
            // SET X = Model or x.Name = "NewName"
            select SaveChanges();

Could something like this be done at all?

like image 761
James Avatar asked Sep 28 '22 18:09

James


2 Answers

From MSDN:

In a query that returns a sequence of values, the query variable itself never holds the query results and only stores the query commands. Execution of the query is deferred until the query variable is iterated over in a foreach or for loop. This is known as deferred execution; that is, query execution occurs some time after the query is constructed. This means that you can execute a query as frequently as you want to. This is useful when, for example, you have a database that is being updated by other applications. In your application, you can create a query to retrieve the latest information and repeatedly execute the query, returning the updated information every time.

So, your query will be executed when you do the foreach to update your entities. As @recursive said, LINQ is useful when you need to do a query over a collection, not to update data specifically.

As an aditional info, you can also force immediate execution. This is useful when you want to cache the results of a query,for example, when you want to use some functionalities that Linq to Entities doesn't support. To force immediate execution of a query that does not produce a singleton value, you can call the ToList method, the ToDictionary method, or the ToArray method on a query or query variable.

like image 200
octavioccl Avatar answered Oct 06 '22 20:10

octavioccl


I believe the best possible way to do so would be to write an extension method which can be done by creating a static class:

public static class Extensions
{
    public static IEnumerable<T> Remove<T>(this DbSet<T> Input, Func<T, Boolean> Objects) where T : class
    {
        var I = Input.Where(Objects).ToList();
        for (int i = 0; i < I.Count; i++)
        {
            Input.Remove(I[i]);
        }
            return Input;
    }
    public static IEnumerable<T> Update<T>(this DbSet<T> Input, Func<T, Boolean> Objects, Action<T> UpdateAction) where T : class
    {
        var I = Input.Where(Objects).ToList();
        I.ForEach(UpdateAction);
        return I;
    }
}

Then you can do:

var Context = new EFContext();
Context.YourTable.Remove(x=> x.Id == 1);
Context.SaveChanges();
// OR
Context.Update((x=> x.Id == 1), (y)=> {y.Title = "something"});
Context.SaveChanges();
like image 27
Transcendent Avatar answered Oct 06 '22 19:10

Transcendent