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();
精彩评论