var q = (dc.tblHelpCentreQuestions.Where(c => c.userID == UserID));
q.OrderByDescending(c => c.dateSubmitted);
I'm just getting used to Linq, and I'm sorting my records by date submitted descending, but could someone explain to me why I have to do c => c.dateSubmitted and not just pass in tblHelpCentreQuestions.dateSubmitted? What does the c=> do and why is it needed?
It is a lambda expression. Read about them here.
Also note that OrderByDescending returns a new IEnumerable, it does not do an in-place sort. You will want to read about Linq basics here.
q = tblHelpCentreQuestions is enumerable. It does not have dateSubmitted property. Its elements have that property. C stands exactly for that element
the c=>c.dateSubmitted is a lambda expression, they are used a lot with Linq. In this case, it's kind of a selector. it defines which property of your class to order by. tblHelpCentreQuestions.dateSubmitted in the other hand is just a "value", it doesn't give info about the property.
Put simply, a lambda expression is an anonymous method. a method needs parameters, that's what the c=> is for. if you have a method that takes two arguments (say, sender and args), you would have something like (sender, args)=>. There are Expression Lambdas, which have one expression as their body (as is the case with your example), and Statement Lambdas which can have more than one instruction (or statement), and thus need a block to delimit it. (sender, args)=>{ ... }. It may or may not have a return value.
Hope this helps :)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have don't understand the <...> syntax, is this is function?
Could anyone explain me this line of code?
ApplyPropertyChange<AgreementTransaction, int>(ref _agreementId, o => o.AgreementId, value);
Based on the named of the method (ApplyPropertyChange) and the type of arguments, that looks like a setter for an element in a set of elements. The <> use is to pass the type of element, in this case it is an AgreementTransaction; the second argument of type int is most likely what to expect value to be or the result of the Func to be.
ApplyPropertyChange(ref _agreementId, o => o.AgreementId, value);
It looks like it is taking the set of elements, finding the element in the set by using its AgreementId, and then setting the value shown.
It could in some ways be rewritten like this at a basic level.
foreach(AgreementTransaction el in setOfElements)
{
if( (int)el.AgreementId == _agreementId )
{
el.AgreementId = value;
}
}
The Func<> passed in is referred to as a predicate. It is essentially a delegate which will project an AgreementTransaction into an int.
Think of it like this:
AgreementTransactions.Select( o => o.AgreementId );
or in a broader example:
List<AgreementTransaction> AgreementTransactions = someListOfThem;
List<int> result = new List<int>();
foreach(AgreementTransaction agree in AgreementTransactions)
{
result.Add(agree.AgreementId);
}
Overall, there is a lot more going on that I will not get into with regards to Lambda expressions, Func declarations, and delegates. You can read more on that from MSDN: https://msdn.microsoft.com/en-us/library/bb397687.aspx
This syntax:
o => o.AgreementId
is the use of the lambda operator.
Specifically, this creates an anonymous function that takes one parameter, named o, and where the body is simply return o.AgreementId.
So this:
o => o.AgreementId
is short-hand for this:
delegate(var o)
{
return o.AgreementId;
}
however you can't really specify var o like that, but for the lambda operator the compiler can infer the right type for o depending on the delegate the function is fitted into, and this is where you need to go to the ApplyPropertyChange method, most likely it looks something like this:
public void ApplyPropertyChange<T1,T2>(ref T2 value, Func<T1,T2> getValue, T1 inputValue)
in which case T1 and T2 are inferred from o.AgreementId and ref _agreementId.
=> Is the lambda operator. Some people say that you pronounce it as "goes to". It is a shortcut for a delegate.
Maybe the sentence above holds several new concepts for you. The idea behind a delegate is that you don't give the value as a parameter of a function, but a function. In fact the parameter is a value, but the value is not an integer, or an object; it is of a function type.
If you call a function like F(x) and you you give a value 4 as a parameter, you'll tell this function that whenever it sees the letter X it should use the value 4.
The same is with delegate. If you have a function with a delegate D as a parameter and you call it with the parameter Sin(x) you say to the function that whenever it uses a call to D it should call Sin(x).
The traditional way of using delegates involved quite some typing. With the introduction of lambda expression this was made much easier.
The lambda expression is heavily used in Linq. Whenever you need to do things with sequences like arrays / lists / collections / sets, whatever, and you would normally use foreach Linq will make live easier for you.
For example, let's say you'll have a sequence of Persons. I use here the term sequence, because I don't care whether it is an array, a list, a set, a collection, whatever. The only think I demand from it is that I can ask for the first element and for the next element in the sequence until there are no more elements. In short: I demand that the sequence is Enumerable.
Suppose from this sequence I only want the Persons with a value for the FirstName property "John". For this the static function Enumerable.Where is used. The result is an IEnumerable of the same type as my original sequence:
IEnumerable<Person> personsNamedJohn = Persons
.Where(p => p.FirstName == "John");
Here you'll see the =>. You could phrase it as:
From the sequence Persons, take each person (let's call it p), where p.FirstName == "John".
I quite often keep it readable by giving my sequences a plural identifier (Persons) and instead of p I write the singular identifier:
IEnumerable<Person> personsNamedJohn = Persons
.Where(person => person.FirstName == "John");
IEnumerable<Shape> circles = Shapes
.Where(shape => shape.ShapeType == Shape.Circle);
There are a lot of other Linq functions where you use lambda. We saw that the function where gives you the elements of the sequence that match the predicate. The function Select will use each item of the sequence to create another item.
IEnumerable<Address> addressesOfPersonsNamedJohn = Persons
.Where(person => person.FirstName == "John")
.Select(person => new Address(person.Street, person.City, person.ZIP));
This is: from all Persons, take only the persons whith a firstname of "John", and from each of these persons take the Street, City and ZIP property as parameters for the constructor of an Address object. The result is a sequence of Addresses.
In the beginning I found the use of the lambda operator quite confusing, but once I understood it, it became very useful. Whenever I would write foreach, I find that it can quite often be written much shorter and easier to understand if I use a Linq statement with a lambda expression.
The standard linq operatores was a good starting point for me to understand linq, delegates and lambda
OK, this is doing my head in - I'm not even sure how to search for this.
Here is the first part of my function:
var rules = context.Rules.Include(r => r.CreatedBy).Include(r => r.ModifiedBy);
IUserManager um = GetUserManager();
var currentUser = um.GetCurrent();
Can someone tell me why this works:
return rules.Where(delegate(Rule r)
{
return r.CreatedBy.CompanyID == currentUser.CompanyID;
});
but this doesn't:
return rules.Where(r => r.CreatedBy.CompanyID == currentUser.CompanyID);
It's EF Code first and CreatedBy and ModifiedBy are both virtual properties.
r.CreatedBy and currentUser are both instances of the same class (if you didn't already work this out)
What the second snippet is returning is an empty list. It's as though the eager loading isn't working and the lambda doesn't cause a lazy load.
Note: I've just discovered that if I change the first line to
var rules = context.Rules.Include(r => r.CreatedBy)
.Include(r => r.ModifiedBy).ToList()
then the lambda works. The question still stands though. Why to I have to use the ToList() or the delegate. I'm doing the same thing elsewhere in the same class and it works as I'd expect.
Thanks
This is because lambdas can be implicitly converted to delegates or to expression trees. In the first case, the delegate is converted to an expression tree because rules is IQueryable<> and overload resolution chooses Queryable.Where. When you use the anonymous function, however, that can't be converted to an expression tree, so overload resolution has to choose Enumerable.Where.
When you make rules into a List<>, that forces overload resolution to choose Enumerable.Where, because List<> does not implement IQueryable<>. You could use AsEnumerable() to achieve the same effect without the overhead of creating the list.
As to why this doesn't work when you're "doing the same thing elsewhere in the same class and it works as I'd expect," we might be able to help if you give an example of code that does work.
In reference to the answer proposed in this post, can anyone explain why LINQPad won't generate any SQL for this?
var query = Products.Select(p => new
{
Orders = p.Orders.OrderByWithDirection(x => x.PurchaseDate, true)
});
The exception is as follows:
NotSupportedException: Method 'System.Linq.IOrderedEnumerable1[LINQPad.User.Order] OrderByWithDirection[Phase,String](System.Collections.Generic.IEnumerable1[LINQPad.User.Order], System.Func`2[LINQPad.User.Order,System.String], Boolean)' has no supported translation to SQL.
The problem is not that it's part of an anonymous type - the problem is that you don't actually call OrderByWithDirection directly... instead, you build up an expression tree within the projection and that expression tree contains a reference to OrderByWithDirection, which LINQ to SQL (or EF, or whatever) doesn't know about.
I can't think of any nice fix for this other than an expression tree visitor which goes through the expression tree and replaces the call with either OrderBy or OrderByDescending based on the second argument - which would have to be a constant, of course. Even that's going to be far from trivial.
To be honest, I would probably take a low-tech approach - keep as much of the query the same as you can, and then conditionally call OrderBy or OrderByDescending at the end:
var mainQuery = ...; // Stuff which is in common
var query = direction
? mainQuery.Select(p => new { Orders = p.Orders.OrderBy(x => x.PurchaseDate) })
: mainQuery.Select(p => new { Orders = p.Orders.OrderByDescending(x => x.PurchaseDate) });
As an aside, I assume your real query has more properties in the anonymous type? There's rarely any good reason to create an anonymous type with a single property.
Hi I have a collection of Objects in a Listview and i need to know if i can iterate through them with a lambda expression. and call a method on it in the expression.
Lets say i need to save a group of people to a database.
List<People> someList;
someList.Select(person => person.Save());
is this possible to do? so far i have not been able to get it working.
thanks
You can use the ForEach method of a generic list:
List<People> someList;
someList.ForEach(person => person.Save());
someList.ForEach(p => p.Save());
Sounds like you want a foreach statement:
foreach(People p in someList)
{
p.Save();
}
But if you really want to do it in lambda expressions and LINQ, then your problem with the above code is that .Select(...) returns an IEnumerable/IQueryable, which creates a new query but doesn't execute your lambda expressions.
You could force the lambda to evaluate by calling an extension method that forces an enumeration of the data the IEnumerable/IQueryable represents. For instance by doing:
someList.Select(person => person.Save()).Count();
but this also assumes your Save() method returns non-void.
Edit:
As others have pointed out, if you're working specifically with a List<>, then you can also do:
someList.ForEach(person => person.Save());
I'm trying to get a handle on if there's a good time to use standard linq keywords or linq extension methods with lambda expressions. They seems to do the same thing, just are written differently. Is it purely a matter of style?
var query = from p in Products
where p.Name.Contains("foo")
orderby c.Name
select p;
// or with extension methods:
var query = Products
.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name);
They're very similar with the second example being a bit more terse, but perhaps less expressive if you don't know what the => is doing.
Other than writing terse code, are there other advantages to using the extension methods as opposed to the LINQ syntax?
Honestly, sometimes it can be situational once you start using Funcs and Actions. Say you are using these three funcs:
Func<DataClasses.User, String> userName = user => user.UserName;
Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;
As you can see the first one replaces the lamdba expression to get the user name, the second replaces a lamdba expression used to check if the ID is lower than 10, and let's face it, the third should be pretty easy to understand now.
NOTE: This is a silly example but it works.
var userList =
from user in userList
where userIDOverTen(user)
select userName;
Versus
var otherList =
userList
.Where(IDIsBelowNumber)
.Select(userName)
In this example, the second is a little less verbose since the extension method can make full use of the Func, but he Linq expression can't since it is look just for a Boolean rather than a Func that returns boolean. However, this is where it might be better to use the expression language. Say you already had a method that takes in more than just a user:
private Boolean IDIsBelowNumber(DataClasses.User user,
Int32 someNumber, Boolean doSomething)
{
return user.UserID < someNumber;
}
Note: doSomething is just there because of the where extension method being ok with a method that takes in a user and integer and returns boolean. Kind of annoying for this example.
Now if you look at the Linq query:
var completeList =
from user in userList
where IDIsBelowNumber(user, 10, true)
select userName;
You're good for it. Now the Extension Method:
var otherList =
userList
.Where(IDIsBelowNumber????)
.Select(userName)
Without a lambda expression, I really can't call that method. So now what I have to do is create a method that creates a Func based off the original method call.
private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
{
return user => IDIsBelowNumber(user, number, true);
}
And then plug it in:
var otherList =
userList
.Where(IDIsBelowNumberFunc(10))
.Select(userName)
So you can see, sometimes it may just be easier to use the query approach at times.
One advantage to using LINQ extension methods (method-based queries) is that you can define custom extension methods and it will still read fine.
On the other hand, when using a LINQ query expression, the custom extension method is not in the keywords list. It will look a bit strange mixed with the other keywords.
Example
I am using a custom extension method called Into which just takes a string:
Example with query
var query = (from p in Products
where p.Name.Contains("foo")
orderby c.Name
select p).Into("MyTable");
Example with extension methods
var query = Products
.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name)
.Into("MyTable");
In my opinion the latter, using a method-based query, reads better when you have custom extension methods.
I think it's a good idea not to use them together and choose one and stick with it.
Mostly it's personal taste, but in the query syntax (Comprehension method) not all operators are available as was said before.
I find the Extension Methods syntax more in line with the rest of my code. I do my SQL in SQL. It's also very easy to build your expression just by adding everything on top of eachother with the extension methods.
Just my two cents.
As I cannot make comments yet I want to make one here to the answer of Programming Tool:
Why make a whole new method for the last example?? Can't you just use:
.Where(user => IDIsBelowNumber(user, 10, true))
They compile the same, and are equivalent. Personally, I prefer the lambda (extension) methods for most things, only using the statements (standard) if I'm doing LINQ to SQL or otherwise trying to emulate SQL. I find that the lambda methods flow better with code, whereas the statements are visually distracting.
I prefer the extension method syntax when I use Linq methods that have no query syntax equivalent, such as FirstOrDefault() or others like that.
I like to use the query syntax when its really a query, ie a lazy expression which evaluates on demand.
A method that looks like regular method calls (method syntax or the lambda syntax) doesn't look lazy enough, so I use that as a convention. For eg,
var query = from p in Products
where p.Name.Contains("foo")
orderby p.Name
select p;
var result = query.ToList(); //extension method syntax
If it's a not a query, I like the fluent style which looks to me consistent with other eagerly executing calls.
var nonQuery = Products.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name)
.ToList();
It helps me to differentiate the two styles of calls better. Of course there are situations where you will be forced to use method syntax anyway, so my convention is not very compelling enough.
One advantage of extension methods/lynda expressions is the additional operators that is offered like Skip and Take. For example, if you are creating a pagination method, being able to skip the first 10 records and take the next 10 is easy to implement.