Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple way to update IEnumerable objects using LINQ

Tags:

c#

linq

Assume I have a business object like this,

class Employee
    {
        public string name;
        public int id;
        public string desgination;
        public int grade;
    }

    List<Employee> lstEmp = new List<Employee>()
        {
            new Employee() { name="A",desgination="SE",id=1},
            new Employee() { name="b",desgination="TL",id=2},
            new Employee() { name="c",desgination="PL",id=3},
            new Employee() { name="d",desgination="SE",id=4},
            new Employee() { name="e",desgination="SSE",id=5},
        };

And if I want to update the employee grade to 3 whose designation is "SE", then I have to write something like this

lstEmp=lstEmp.Select(x =>
            {
                x.grade = (x.desgination == "SE") ? 3 : x.grade;
                    return x;
            }).ToList();

But here when using select it will generate new employee object everytime, not updating the existing lstEmp, so I have to reassgin the updated list to lstEmp.

It seems to me it affects the performance when updating large updates frequently. Is there a workaround for this?

like image 355
oscar Avatar asked Oct 14 '10 06:10

oscar


People also ask

How do you update a record in LINQ?

To update a row in the databaseQuery the database for the row to be updated. Make desired changes to member values in the resulting LINQ to SQL object. Submit the changes to the database.

How do I edit IEnumerable?

IEnumerable is readonly. You can not modify it. If you want to modify collection, then consider to change it to List . Perhaps using a List<string> would be more appropriate?

Can you use LINQ on IEnumerable?

All LINQ methods are extension methods to the IEnumerable<T> interface. That means that you can call any LINQ method on any object that implements IEnumerable<T> . You can even create your own classes that implement IEnumerable<T> , and those classes will instantly "inherit" all LINQ functionality!

How does except work in c#?

The Except() method requires two collections. It returns a new collection with elements from the first collection which do not exist in the second collection (parameter collection). Except extension method doesn't return the correct result for the collection of complex types.


2 Answers

Actually, your existing Select call is modifying the original objects themselves - it's not creating new employee objects. What makes you think it is creating new Employee instances? After all, you haven't got new Employee anywhere within the lambda expression.

You could iterate through the results of calling Select without ever calling ToList, and you'd still see changes afterwards. This means your projection has side-effects - that's generally a bad idea. You do have to make something iterate over the results of the projection though. Just calling Count() would do it, for example. LINQ queries use deferred execution in many cases: they don't apply the projection/predicate/etc until the result is needed.

LINQ is designed to work in a functional way: side-effects are discouraged, just as you wouldn't expect a normal SELECT query on a database to change the contents of the table it's querying. Side-effect-free code is great in terms of readability and the ability to reason about code.

If you want to change values rather than create new ones, I would suggest a simple foreach loop instead. It's not what LINQ is designed for. However, I would personally try to stick to immutable types, use LINQ, and measure the performance as you go - I suspect you'll find that in many cases it's not as bad as you think.

like image 107
Jon Skeet Avatar answered Oct 03 '22 04:10

Jon Skeet


I believe default LINQ methods doenst support inline updates. but you can create your own extension methods to achive this

  public static void Update<TSource>(this IEnumerable<TSource> outer, Action<TSource> updator)
        {
            foreach (var item in outer)
            {
                updator(item);
            }


        }

and use it like this

 lstEmp.Update(x => x.grade = (x.desgination == "SE") ? 3 : x.grade);
like image 29
RameshVel Avatar answered Oct 03 '22 02:10

RameshVel