Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update object in IEnumerable<> not updating?

I have an IEnumerable of a POCO type containing around 80,000 rows and a db table (L2E/EF4) containing a subset of rows where there was a "an error/a difference" (about 5000 rows, but often repeated to give about 150 distinct entries)

The following code gets the distinct VSACode's "in error" and then attempts to update the complete result set, updating JUST the rows that match...but it doesn't work!

var vsaCodes = (from g in db.GLDIFFLs
  select g.VSACode)
  .Distinct();

foreach (var code in vsaCodes)
 {
  var hasDifference = results.Where(r => r.VSACode == code);
  foreach (var diff in hasDifference)
   diff.Difference = true;
 }

 var i = results.Count(r => r.Difference == true);

After this code, i = 0

I've also tried:

foreach (var code in vsaCodes)
    {
        results.Where(r => r.VSACode == code).Select(r => { r.Difference = true; return r; }).ToList();
    }

How can I update the "results" to set only the matching Difference property?

like image 435
BlueChippy Avatar asked Sep 05 '11 06:09

BlueChippy


2 Answers

Assuming results is just a query (you haven't shown it), it will be evaluated every time you iterate over it. If that query creates new objects each time, you won't see the updates. If it returns references to the same objects, you would.

If you change results to be a materialized query result - e.g. by adding ToList() to the end - then iterating over results won't issue a new query, and you'll see your changes.

like image 175
Jon Skeet Avatar answered Nov 10 '22 06:11

Jon Skeet


I had the same kind of error some time ago. The problem is that linq queries are often deferred and not executed when it appears you are calling them.

Quotation from "Pro LINQ Language Integrated Query in C# 2010":

"Notice that even though we called the query only once, the results of the enumeration are different for each of the enumerations. This is further evidence that the query is deferred. If it were not, the results of both enumerations would be the same. This could be a benefit or detriment. If you do not want this to happen, use one of the conversion operators that do not return an IEnumerable so that the query is not deferred, such as ToArray, ToList, ToDictionary, or ToLookup, to create a different data structure with cached results that will not change if the data source changes."

Here you have a good explanation with examples of it:

http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx

Regards

like image 40
GoRoS Avatar answered Nov 10 '22 05:11

GoRoS