Kindly let me know the difference between the "where" in (1) and "where()" in (2).
When to use "where" and "where()" ?
List<Person> pList =
new List<Person>
{
new Person
{EmpNo=1,FirstName="Marc",LastName="Loel",Salary=3434},
new Person
{EmpNo=2, FirstName="Steve",LastName="Kaith",Salary=4545},
new Person
{EmpNo=3,FirstName="Neol",LastName="Henk",Salary=2222},
};
(1) var v = from p in pList where p.EmpNo == 1 select new { p.FirstName };
(2) var query =pList .Where(p => p.EmpNo == 1)
.Select(p => new { p.FirstName});
The difference is that one form is easier to read and the other form is more difficult to read. Trouble is, about half the people think the first one is easier, and half the people think the second one is the easier one! Choose the one you like best and stick with it; they mean exactly the same thing.
There is no real difference. The first where (and select) are a special in-language query expression that get translated by the compiler into those other lambda-based Where and Select methods.
It's just syntactic sugar. In fact, if you just have a class with the correct Where method, even if the class isn't enumerable, you can use the syntactic magic:
class MyClass
{
public IQueryable<int> Where(Func<int, bool> predicate)
{
return Enumerable.Range(1, 100).AsQueryable();
}
}
static void Main(string[] args)
{
var q = from p in new MyClass()
where p == 10
select p;
}
This doesn't do anything, but it builds and will call that method.
I believe they are identical. Microsoft created the syntax in (1) for readability, but the compiler handles it as (2).
There is no difference. Number (1) is just written with some syntactic sugar.
Quick look at the code in reflector and it looks like this:
var v = pList.Where<Person>(delegate (Person p) {
return (p.EmpNo == 1);
}).Select(delegate (Person p) {
return new { FirstName = p.FirstName };
});
var query = pList.Where<Person>(delegate (Person p) {
return (p.EmpNo == 1);
}).Select(delegate (Person p) {
return new { FirstName = p.FirstName };
});
As you can see, they are exactly the same.
The difference (if you want to be picky) is that the first one is LINQ, and the second one isn't.
LINQ is the integrated query language that you see in the first example, and the compiler turns it into using the extension methods seen in the second example.
There are some additional features in.where () method e.g. you can use index extension of where method.
But for given example its just readability.
Related
Is there something similar to jQuery's end() function in LINQ?
So I could modify a result set from a previous select?
There is nothing similar in .NET. There is not even a guarantee that an IEnumerable<> is enumerable twice (or that the two results will be the same). Often each enumeration will redo the query (or whatever it's). So for example if you do:
** CODE THAT REALLY WORKS, BUT BADLY! (SEE BELOW) **
var persons = from p in ctx.Persons select p;
foreach (var person in persons) { }
foreach (var person in persons) { }
where ctx.Persons is a table in an SQL Server, each foreach will redo the query.
I think it would be possible to build something similar in .NET (a caching stacked enumerator), but you would have to rewrite all the LINQ methods (and this only for LINQ-to-Objects)
There is another problem, more semantical: LINQ is a language for queries, there is no ForEach method. The methods of jQuery are different. They "act" on the items returned by the query. So the only "correct" place for something like this in .NET would be to be able to have more than one result-set for the same query... Something like:
** CODE NOT WORKING, JUST AS AN EXAMPLE **
var res = (from p in myItems select p).StackfulEnumerable()
.Count(p => p.SomeProperty == 1)
.Pop() // like the End() of jquery
.Count(p => p.SomeProperty == 2);
and res in some is now a Tuple<int, int> (in some way... technically it would be very very complex to make it return a Tuple<int, int> in a type safe way, because in C# you can't build type safe generic methods with variable number of arguments)
Now, clearly someone could do this:
** CODE THAT REALLY WORKS **
var enu = // my enumerable
var res = from p in new[] { enu }
let res1 = p.Where(q => q.Prop == 1)
let res2 = p.Where(q => q.Prop == 2)
select Tuple.Create(res1.ToArray(), res2.ToArray());
and it would be ok, but remember that you are enumerating enu twice!
Clearly you could play it safe:
** CODE THAT REALLY WORKS **
var res = from p in new[] { enu.ToList() }
let res1 = p.Where(q => q.Prop == 1)
let res2 = p.Where(q => q.Prop == 2)
select Tuple.Create(res1.ToArray(), res2.ToArray());
now at least you know you'll enumerating twice something that is safe to enumerate any number of times you want.
Note that you could write:
** CODE THAT REALLY WORKS **
select Tuple.Create(res1, res2);
but then every time you would enumerate the two enumerables of the Tuple you would enumerate again the "source" (unless you used the ToList(), as in the second example)
Here is some sample code I have basically written thousands of times in my life:
// find bestest thingy
Thing bestThing;
float bestGoodness = FLOAT_MIN;
foreach( Thing x in arrayOfThings )
{
float goodness = somefunction( x.property, localvariable );
if( goodness > bestGoodness )
{
bestGoodness = goodness;
bestThing = x;
}
}
return bestThing;
And it seems to me C# should already have something that does this in just a line. Something like:
return arrayOfThings.Max( delegate(x)
{ return somefunction( x.property, localvariable ); });
But that doesn't return the thing (or an index to the thing, which would be fine), that returns the goodness-of-fit value.
So maybe something like:
var sortedByGoodness = from x in arrayOfThings
orderby somefunction( x.property, localvariable ) ascending
select x;
return x.first;
But that's doing a whole sort of the entire array and could be too slow.
Does this exist?
This is what you can do using System.Linq:
var value = arrayOfThings
.OrderByDescending(x => somefunction(x.property, localvariable))
.First();
If the array can be empty, use .FirstOrDefault(); to avoid exceptions.
You really don't know how this is implemented internally, so you can't assure this will sort the whole array to get the first element. For example, if it was linq to sql, the server would receive a query including the sort and the condition. It wouldn't get the array, then sort it, then get the first element.
In fact, until you don't call First, the first part of the query isn't evaluated. I mean this isn't a two steps evaluation, but a one step evaluation.
var sortedValues =arrayOfThings
.OrderByDescending(x => somefunction(x.property, localvariable));
// values isn't still evaluated
var value = sortedvalues.First();
// the whole expression is evaluated at this point.
I don't think this is possible in standard LINQ without sorting the enuermable (which is slow in the general case), but you can use the MaxBy() method from the MoreLinq library to achieve this. I always include this library in my projects as it is so useful.
http://code.google.com/p/morelinq/source/browse/trunk/MoreLinq/MaxBy.cs
(The code actually looks very similar to what you have, but generalized.)
I would implement IComparable<Thing> and just use arrayOfThings.Max().
Example here:
http://msdn.microsoft.com/en-us/library/bb347632.aspx
I think this is the cleanest approach and IComparable may be of use in other places.
UPDATE
There is also an overloaded Max method that takes a projection function, so you can provide different logic for obtaining height, age, etc.
http://msdn.microsoft.com/en-us/library/bb534962.aspx
I followed the link Porges listed in the comment, How to use LINQ to select object with minimum or maximum property value and ran the following code in LINQPad and verified that both LINQ expressions returned the correct answers.
void Main()
{
var things = new Thing [] {
new Thing { Value = 100 },
new Thing { Value = 22 },
new Thing { Value = 10 },
new Thing { Value = 303 },
new Thing { Value = 223}
};
var query1 = (from t in things
orderby GetGoodness(t) descending
select t).First();
var query2 = things.Aggregate((curMax, x) =>
(curMax == null || (GetGoodness(x) > GetGoodness(curMax)) ? x : curMax));
}
int GetGoodness(Thing thing)
{
return thing.Value * 2;
}
public class Thing
{
public int Value {get; set;}
}
Result from LinqPad
I am completely new to Linq and wondering if you can help me understand the difference between the following Linq? For example...
//normal select
var contacts = entity.Contacts.Select(n => n.FirstName);
//select new
var contacts2 = entity.Contacts.Select(n => new { n.FirstName });
//normal select output
foreach (var c in contacts)
Response.Write(c + "<br/>");
//select new output
foreach (var c in contacts2)
Response.Write(c.FirstName + "<br/>");
The only difference I can see is that in the normal select, the firstname (string) is stored in the collection, whereas in the select new, a contact object is stored in the collecton and the firstname being accessed by its property. Also the select new returns the properties only selected in the statement.
Another difference I noticed is that you can return multiple specific properties in the select new.
In what scenario would you choose one over the other?
Thanks for the help.
n => n.FirstName gives you a string
n => new { n.FirstName } gives you an anonymous type, with one string property called FirstName
In general, an anonymous type with just one property is probably not what you're looking for, so I'd go for the first option.
To support Richard Ev's answer:
If you are not familiar with Anonymous types, crack up ildasm and give your exe as an input to it.
You will get something like this:
The thing that you see starting with <>f_AnonymousType() is the one that Richard Ev is talking about. Your syntax of new got translated into a new class (the name was decided by compiler). That is why var keyword is so helpful working with anonymous type.
NOTE: Right before posting this question it occurred to me there's a better way of doing what I was trying to accomplish (and I feel pretty stupid about it):
IEnumerable<string> checkedItems = ProductTypesList.CheckedItems.Cast<string>();
filter = p => checkedItems.Contains(p.ProductType);
So OK, yes, I already realize this. However, I'm posting the question anyway, because I still don't quite get why what I was (stupidly) trying to do wasn't working.
I thought this would be extremely easy. Turns out it is giving me quite a headache.
The basic idea: display all the items whose ProductType property value is checked in a CheckedListBox.
The implementation:
private Func<Product, bool> GetProductTypeFilter() {
// if nothing is checked, display nothing
Func<Product, bool> filter = p => false;
foreach (string pt in ProductTypesList.CheckedItems.Cast<string>()) {
Func<Product, bool> prevFilter = filter;
filter = p => (prevFilter(p) || p.ProductType == pt);
}
return filter;
}
However, say the items "Equity" and "ETF" are both checked in ProductTypesList (a CheckedListBox). Then for some reason, the following code only returns products of type "ETF":
var filter = GetProductTypeFilter();
IEnumerable<Product> filteredProducts = allProducts.Where(filter);
I guessed it might have had something to do with some self-referencing messiness where filter is set to, essentially, itself or something else. And I thought that maybe using ...
filter = new Func<Product, bool>(p => (prevFilter(p) || p.ProductType == pt));
...would do the trick, but no such luck. Can anybody see what I am missing here?
I believe you have a modified closure problem here. The pt parameter is bound into the lambda expression but changes as the loop progresses. It's important to realize the when a variable is referenced in a lambda it is the variable that is captured, not the value of the variable.
In loops this has a very significant ramification - because the loop variable is changing, not being redefined. By creating a variable inside the loop, you are creating a new variable for each iteration - which then alows the lambda to capture each independently.
The desired implementation would be:
foreach (string pt in ProductTypesList.CheckedItems.Cast<string>()) {
string ptCheck = pt;
Func<Product, bool> prevFilter = filter;
filter = p => (prevFilter(p) || p.ProductType == ptCheck);
}
Eric Lippert has written about this specific situation:
http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
http://blogs.msdn.com/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx
Also, see the question Access to Modified Closure (2) for a good explanation of what happens with closure variables. There's also an series of articles on the blog The Old New Thing that has an interesting perspective on this:
http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx
http://blogs.msdn.com/oldnewthing/archive/2006/08/03/687529.aspx
http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx
It has to do with closures. The variable pt will always refer to the last value of the for loop.
Consider the following example where the output is the one expected because it's using a variable that is scoped inside the for loop.
public static void Main(string[] args)
{
var countries = new List<string>() { "pt", "en", "sp" };
var filter = GetFilter();
Console.WriteLine(String.Join(", ", countries.Where(filter).ToArray()));
}
private static Func<string, bool> GetFilter()
{
Func<string, bool> filter = p => false;
foreach (string pt in new string[] { "pt", "en" })
{
Func<string, bool> prevFilter = filter;
string name = pt;
filter = p => (prevFilter(p) || p == name);
}
return filter;
}
Since you're looping and setting the filter type to itself, you're setting the product type to the last pt in each case. It's a modified closure and since it's delay bound, you need to copy it on each loop, like this:
foreach (string pt in ProductTypesList.CheckedItems.Cast<string>()) {
var mypt = pt;
Func<Product, bool> prevFilter = filter;
filter = p => (prevFilter(p) || p.ProductType == mypt);
}
This should result in the right result, otherwise the last pt is used for all equality checks.
I know there are a lot of examples of this on the web, but I can't seem to get this to work.
Let me try to set this up, I have a list of custom objects that I need to have limited on a range of values.
I have a sort variable that changes based on some action on the UI, and I need to process the object differently based on that.
Here is my object:
MyObject.ID - Just an identifier
MyObject.Cost - The cost of the object.
MyObject.Name - The name of the object.
Now I need to filter this based on a range in the cost, so I will have something similar to this, considering that I could be limiting by Either of my bottom two properties.
var product = from mo in myobject
where mo.Cost <= 10000
or
var product = from mo in myobject
where mo.Name equals strName
Now I have the dynamic linq in my project, but I'm not figuring out how to get it to actually work, as when I do some of the examples I am only getting:
Func<Tsourse>bool> predicate
as an option.
Update:
I am trying to find a solution that helps me Objectify my code, as right now it is a lot of copy and paste for my linq queries.
Update 2:
Is there an obvious performance difference between:
var product = from mo in myobject
... a few joins ...
where mo.Cost <= 10000
and
var product = (from mo in myobject
... a few joins ...)
.AsQueryable()
.Where("Cost > 1000")
Maybe not directly answering your question, but DynamicQuery is unnecessary here. You can write this query as:
public IEnumerable<MyObject> GetMyObjects(int? maxCost, string name)
{
var query = context.MyObjects;
if (maxCost != null)
{
query = query.Where(mo => mo.Cost <= (int)maxCost);
}
if (!string.IsNullOrEmpty(name))
{
query = query.Where(mo => mo.Name == name);
}
return query;
}
If the conditions are mutually exclusive then just change the second if into an else if.
I use this pattern all the time. What "Dynamic Query" really means is combining pure SQL with Linq; it doesn't really help you that much with generating conditions on the fly.
using System.Linq;
var products = mo.Where(x => x.Name == "xyz");
var products = mo.Where(x => x.Cost <= 1000);
var products = mo.Where(x => x.Name == "xyz" || x.Cost <= 1000);
Read this great post on DLINQ by ScottGu
Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)
You would need something like
var product = myobject.Where("Cost <= 10000");
var product = myobject.Where("Name = #0", strName);
If you downloaded the samples you need to find the Dynamic.cs file in the sample. You need to copy this file into your project and then add
using System.Linq.Dynamic; to the class you are trying to use Dynamic Linq in.
EDIT: To answer your edit. Yes, there is of course a performance difference. If you know the variations of filters beforehand then I would suggest writing them out without using DLINQ.
You can create your own Extension Method like so.
public static class FilterExtensions
{
public static IEnumerable<T> AddFilter<T,T1>(this IEnumerable<T> list, Func<T,T1, bool> filter, T1 argument )
{
return list.Where(foo => filter(foo, argument) );
}
}
Then create your filter methods.
public bool FilterById(Foo obj, int id)
{
return obj.id == id;
}
public bool FilterByName(Foo obj, string name)
{
return obj.name == name;
}
Now you can use this on an IEnumerable<Foo> very easily.
List<Foo> foos = new List<Foo>();
foos.Add(new Foo() { id = 1, name = "test" });
foos.Add(new Foo() { id = 1, name = "test1" });
foos.Add(new Foo() { id = 2, name = "test2" });
//Example 1
//get all Foos's by Id == 1
var list1 = foos.AddFilter(FilterById, 1);
//Example 2
//get all Foo's by name == "test1"
var list2 = foos.AddFilter(FilterByName, "test1");
//Example 3
//get all Foo's by Id and Name
var list1 = foos.AddFilter(FilterById, 1).AddFilter(FilterByName, "test1");