开发者

Simple way to update IEnumerable objects using 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 lstEm开发者_StackOverflow社区p, 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?


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.


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);


I would Say LINQ is mainaly used for Selection of data once you get the data , you can use ForEach construct to update the data


lstEmp = lstEmp.Select(X => new Employee
        {
            desgination =X.desgination ,
            grade =X.desgination=="SE"?3:X.grade ,
            id=X.id ,
            name =X.name 
        }).ToList();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜