-3

In the following query to pull a list of Customer instances:

List<Customer> customers = _context.Customers.Where(x => x.Age > 30).ToList();

Why do I need the lambda x => x. bit?

If lambda is shorthand for something, what is the longhand version of the same query? Why does the query syntax exist in a way that I need that bit?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
jamheadart
  • 5,047
  • 4
  • 32
  • 63
  • 1
    Does this answer your question? [Lambda for Dummies....anyone, anyone? I think not](https://stackoverflow.com/questions/2167360/lambda-for-dummies-anyone-anyone-i-think-not) – devNull Aug 22 '20 at 23:35
  • @OmG it's in the question, "Why do I need the lambda `x => x.` bit?" – jamheadart Aug 22 '20 at 23:36
  • By "bit" OP means the "part". Why do they need the lambda syntax. The answer is that lambdas aren't the short form, Query syntax is the "short"/alternative form. They get compiled into method calls/lambdas. Not the other way around. So it's either lambda or `from cust in context.Customers where cust.Age > 30` – pinkfloydx33 Aug 22 '20 at 23:37
  • `x => x.` is needed to make sure you are comparing with the current element (`x`) of the iteration instead of something else. – Cid Aug 22 '20 at 23:44
  • Lambdas are just methods. Your method in the case takes a `Customer` and *returns* `true` if the `Customer.Age` is greater than `30`. Internally `Where` is just passing every `Customer` in the *list* to that method (basically just a *loop*), and returns the ones that return `true`. – TheGeneral Aug 23 '20 at 00:07

2 Answers2

3

You need the lambda because that is what the language and framework dictate. Lambdas in this case aren't the short form, but rather the true form.

If something were to be considered the alternative or long form, it would be query syntax.

var customers = (
  from cust 
  in _context.Customers 
  where cust.Age > 30
).ToList()

This gets translated by the compiler into

var customers = _context.Customers.Where(x => x.Age > 30).ToList();

To address something you hint at, Where expects a Func<T, bool>. If you were to leave off the x => x. and tried to do this:

var customers = _context.Customers.Where(Age > 30).ToList();

You'd get a compiler error as this is not valid syntax, refers to a property not in scope and ultimately passes an expression whose best possible type would be bool and not Func<T, bool>

A lambda and a function can be interchangeable. In this case the function needs to accept Customer and return bool. For example you can have a function OlderThan30:

public static bool OlderThan30(Customer c)
{
   return c.Age > 30;
} 

var customers = _context.Customers.Where(x => OlderThan30(x)).ToList();
// or even shorter with a Method Group 
var customers = _context.Customers.Where(OlderThan30).ToList();

The function could even take other arguments:

public static bool IsOlderThan(Customer c, int age)
{
   return c.Age > age;
} 

var customers = _context.Customers.Where(x => IsOlderThan(x, 30)).ToList();
// note method group syntax not valid here

When using Linq2Sql, Entity Framework or other ORMs the Where method accepts both a Func<T, bool> and an Expression<Func<T, bool>>. Expressions and lambdas look the same. The compiler will chose the correct one depending on whether you are working with an IQueryable<T> or an IEnumerable<T>. For Linq2Sql/EF it will be the former.

Please note that in both cases (for these examples) the lambda will work properly; the Func will be executed in memory and the Expression will be translated to SQL. The function version however will not be translatable to SQL and will either raise an exception or will be performed entirely in memory (depending on the ORM)

pinkfloydx33
  • 11,863
  • 3
  • 46
  • 63
  • Ooh ok, I thought lamdas were basically short-hand user-friendlier versions of existing syntax, I think that may be true in some cases, but not so here. Yeah so I was coming from a SQL point of view I would just write `WHERE AGE > 30` and I wondered why the `Where` function existed to need the `x` declaration. Thanks for the answer. I'm a little bit further on my journey. – jamheadart Aug 23 '20 at 00:09
1

You don't need a lambda. What you need is Func<T, bool> for linq2objects and Expression<Func<T, bool>> for linq2sql. For linq2objects you can make a fuction

public static bool IsAgeOK(Customer x)
{
    return x.Age > 30;
}

and then you can write

List<Customer> customers = _context.Customers.Where(IsAgeOK).ToList();

but you can not do the same for linq2sql. Functions are not automatically converted to expressions, lambdas are. You can construct the expression tree manually on your own, but it is much more work.

What you were originally trying to do was something like

public static bool IsAgeOK(Customer ?)
{
    return Age > 30;
}

which could be possible in theory, but it is not consistent with C# syntax, C# simply does not support this.

Antonín Lejsek
  • 6,003
  • 2
  • 16
  • 18
  • Ok I swapped to this as my accepted answer because that makes much more sense to me, the lambda works in place of a function, so I guess by long-hand I was asking what that function was. Thank you! – jamheadart Aug 23 '20 at 12:37