I was having an issue with a LINQ query today and after some debugging I was able to resolve the issue but it seems like a bug to me in the way LINQ works. Here is what I had:
var myitem = context
.items
.OrderByDescending(x => x.DateEdited)
.FirstOrDefault(x => x.fkId == myFkId && x.DateEdited < someDat开发者_开发百科e);
In my database I have a table with some records and I want to retrieve the most recent record that is older than "someDate" and who has a particular foreign key in a column. The above query did not work however. It was returning the oldest record with the matching foreign key. I ended up having to rewrite my query like this to get it to work:
var myitem = context
.items
.Where(x => x.fkId == myFkId && x.DateEdited < someDate)
.OrderByDescending(x => x.DateEdited)
.FirstOrDefault();
In my debugging I found out that the "x.DateEdited < someDate" was re-ordering the IEnumerable so I ended up having to put my OrderByDescending clause after the date check.
Has anybody else run into this issue? Is it a bug or expected functionality?
Even though .OrderByDescending()
returns an IOrderedEnumerable
, the .FirstOrDefault()
is a shortcut to .Where()
which only returns an IEnumerable
which does not guarantee order.
Basically, adding a filter does not guarantee the order of the data. If you look at the generated SQL from the first, you will get a nested subresult from the orderby that is then filtered again.
Generally, if an operation does not explicitly define the output order, you can't depend on the result being in any particular order until you specify/apply it yourself.
Unless you know that ordering an intermediate result will yield performance improvements in the next step of an algorithm, there's no reason to so. Just apply the ordering as a final processing step.
精彩评论