tags:

views:

92

answers:

4

In LINQ to Object context ,can i update an object in memory.

I mean i can create new type like

var query =from e in empList
           select new {id=e.id,salary=e.salary * (10/100) };

can i update an object?

+4  A: 

No; you need to use a foreach loop.

SLaks
This is correct, the foreach loop is designed to operated over an Enumerable... you can even use a for loopLINQ was designed to QUERY collections, not iterate over them
masenkablast
He can't modify the objects created in his example. Anonymous types are immutable.
Kevin Babcock
I don't think he meant to use an anonymous type at all
masenkablast
+2  A: 

Anonymous types are immutable. If the type is not anonymous, you can dump the collection to a List and modify that:

(from e in empList)
.ToList()
.ForEach(e => {
    e.salary = 999;
})
;

Notice I'm using block syntax in the lambda.

ifwdev
However, this will be slower than a `foreach` loop. (Because of the `ToList` call)
SLaks
And, all things being equal, a lambda expression will be slower (to invoke, though not to execute) than normal procedural code. Lambdas are a good idea when they make the code more readable or concise, but I don't see how this is particularly more readable or concise than a simple `foreach` statement.
Adam Robinson
I use LINQPad for a lot of misc tasks involving hundreds of thousands of records. In my experience the ToList() call is negligible compared to other bottlenecks.
ifwdev
.AsParallel().ForAll(x => { e.salary = 999; });Is NOT slower than a foreach loop in .NET 4 btw
ifwdev
@ifwdev: That's certainly not true as an absolute statement. Execute that on a single-core processor and you're needlessly splitting the list into multiple threads to no advantage.
Adam Robinson
Why would it split into multiple threads if there is only one core available?But yes, you are right, it's not true as an absolute statement. In the scenarios where there is any significant performance overhead from calling ToList, I'd think AsParallel would make up for it though.
ifwdev
+2  A: 

That depends on what you're asking.

If you're asking: Can I use a LINQ statement to update data on the elements of a collection? Then the answer is simply no; LINQ is a query language, not a data modification language. Just use a foreach loop on the original collection as you would have done prior to .NET 3.5/C# 3.0. Nothing to see here.

If you're asking Can I update the values on the type I created in the query in my question?, then the answer is "sortof". The type you're creating by using new { ... } is an anonymous type, which makes it immutable (read only). There's no clean way to do what you're after, but you could do something like:

var query = from e in empList
            select new { id = e.id, salary = e.salary / 10.0, record = e }

Doing this will give you a reference to the original object via the record property, which you can change values on. Realize, though, that the values on your anonymous type (id and salary, in this case) will not reflect any changes made to the referenced object in record.

foreach(var element in empList)
{
    element.record.salary = 100.0;
}

This will update the salary property on the original item, but element.salary will still reflect the original value that was calculated in the query, not the new salary value / 10.0.

Adam Robinson
A: 

Sure, that will work just fine.

Note, however, that the object you are create, while looking like and having the same properties as an Emp, will be a distinct object type.

To elaborate, if you were to say:

var query =from e in empList 
select e;

You are creating a collection of Emp objects. When you say:

var query =from e in empList    
select new {id=e.id,salary=e.salary * (10/100) };

You are creating a collection of anonomous objects which have the same form as Emp objects. You can assign values which may be different from the original empList value, while you are creating it, but once that statement is complete, thosee values cannot be changed again. And nothing here will affect the values in empList.

James Curran
No, it won't; anonymous types are immutable.
Adam Robinson