15

I want to do a simple lambda expression like this:

IList<MyEntity1> list = GetSomeList();

MyEntity1 result = list.SingleOrDefault<MyEntityList>(
    e => GetMyEntity2(e) != null && GetMyEntity2(e).Id != null && GetMyEntity2(e).Id > 0
);

That works perfectly, but getting MyEntity2 from MyEntity1 is not so simple so I would like to declare a variable into the lambda expression to save MyEntity2 and use it, instead of calling again and again to GetMyEntity2 method. Is that possible?

Note: The code is just an example that reflects my real case.

Thanks!

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Diego
  • 16,436
  • 26
  • 84
  • 136

3 Answers3

38

Well, first off, are you trying to use this in linq to sql / entity framework / other?

If not, then just do this

list.SingleOrDefault(e => {
   var entity = GetMyEntity2(e);

   return entity != null && entity.Id != null && entity.Id > 0;
});
Darren Kopp
  • 76,581
  • 9
  • 79
  • 93
9

If you want to use the "query comprehension" syntactic form you can do this:

var query = from entity1 in list
            let entity2 = GetMyEntity2(entity1)
            where entity2 != null
            where entity2.Id != null 
            where entity2.Id > 0
            select entity1;
var result = query.SingleOrDefault();

Note also that the middle "where" clause might not be necessary. If "entity2.Id" is a nullable int then it will be correctly checked for null by the lifted > operator.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • @Eric Lippert didn't knew this syntactic. But I think I see clearer and easier to understand @Darren Kopp solution. Thanks anyway! About the middle "where" clause, as I said, this was just an example, those aren't the real clauses. But again thanks anyway, didn't knew I could compare int?. – Diego Jun 15 '11 at 20:19
  • 1
    @Eric - Is there a reason you use multiple wheres instead of a single where with &&? – chrisaut Jun 17 '11 at 06:43
  • 2
    @Steven: Just because it looks nice. Incidentally, Jon Skeet has a blog article today about the performance implications of this choice. They are a bit surprising. – Eric Lippert Jun 17 '11 at 13:43
  • Wouldn't it be better to use `&&` then nested `where` clauses? You can format them to look pretty much the same, they're more expressive ("where x and y" is more expressive than "where x where y") and they result in simpler-to-run code. – configurator Jun 20 '11 at 19:15
  • @configurator: I don't see one way as particularly better or worse than the other. – Eric Lippert Jun 20 '11 at 19:19
  • @configurator if you are doing it on multiple lines in Linq ad the where syntax is nicer as you can add remove clauses easily. – ShuggyCoUk Jun 20 '11 at 23:33
  • Since the matter of multiple "where" condition was mentioned and a blog article on the subject (which is interesting on its own), but no links were provided. I'll take the liberty to do so here: http://msmvps.com/blogs/jon_skeet/archive/2011/06/16/linq-to-objects-and-the-performance-of-nested-quot-where-quot-calls.aspx http://stackoverflow.com/questions/6359980/proper-linq-where-clauses – jahu May 16 '14 at 12:56
6

You can use the Select operator:

IList<MyEntity1> list = GetSomeList();

MyEntity1 result = list
    .Select(x => new { Item = x, Entity2 = GetMyEntity2(x) })    
    .SingleOrDefault(x => x.Entity2 != null && x.Entity2.Id != null && x.Entity2.Id > 0);

Or, since you're not even using the Item after pushing it through GetMyEntity2 you could just have:

MyEntity1 result = list
    .Select(x => GetMyEntity2(x))    
    .SingleOrDefault(x => x != null && x.Id != null && x.Id > 0);
Kirk Woll
  • 76,112
  • 22
  • 180
  • 195
  • Thanks @Kirk Woll, but I found easer @Darren Kopp solution. Does this one have some benefit over the other one? – Diego Jun 15 '11 at 19:58
  • @Diego, in your example, not so much. However, my solution is more general and will work in Linq-To-Sql and such as well. (at least, it would so long as you're not calling custom methods like `GetMyEntity2`). It also has the vague benefit of being "purely functional". – Kirk Woll Jun 15 '11 at 19:59
  • Ok, +1 because I'll have it mind for other cases where the @Darren Kopp solution does not apply, thanks! However for this case I think the answer I was looking for (and simple solution) is @Darren's. – Diego Jun 15 '11 at 20:07