I have the following linq statement that is ordering a list of assets by the sort order of a child item:
Assets.OrderBy(a => a.GalleryItems != null &&
a.GalleryItems.FirstOrDefault(gi => gi.ProductItemCode == productId) != null
? a.GalleryItems.FirstOrDefault(gi => gi.ProductItemCode == productId).SortOrder : 1000);
I was wondering if there was a more efficient way to do this as I would have thought having to do 2 a.GalleryItems.FirstOrDefault(gi => gi.ProductItemCode == productId)
would be pretty poor for performance
1 Answer 1
You're correct, it can be costly.
You can just expand the lambda expression:
Assets.OrderBy(a => {
var item = a.GalleryItems != null
? a.GalleryItems.FirstOrDefault(gi => gi.ProductItemCode == productId)
: null;
return item != null ? item.SortOrder : 1000;
});
[Quick edit]
The above will work correctly only for LINQ 2 Objects queries.
If you're using EF or any other LINQ database provider, you should leave the query as-is, because it will probably be translated to ISNULL(..., 1000)
or something equivalent.
-
\$\begingroup\$ This was what I was after - I was wondering if you could set vars in a lamda, now I know. Thanks! \$\endgroup\$Pete– Pete2014年05月21日 09:52:58 +00:00Commented May 21, 2014 at 9:52
-
\$\begingroup\$ @Pete One important thing here though: it will only work in LINQ 2 Objects. If you're using any database LINQ driver, expanded lambda expressions are not translatable to SQL, at least not by any provider I know. On the other hand, the performance considerations and query structure are also different, since the query will is executed in the database. I added that as an edit so it's clear. \$\endgroup\$Patryk Ćwiek– Patryk Ćwiek2014年05月21日 09:54:24 +00:00Commented May 21, 2014 at 9:54
-
\$\begingroup\$ Ah, I think I'm fine as it is just querying a c# object from cache rather than the db \$\endgroup\$Pete– Pete2014年05月21日 10:53:12 +00:00Commented May 21, 2014 at 10:53