What is LINQ and what is not LINQ? - linq

I've seen examples where all of the following are referred to as LINQ.
var y = _context.Persons;
IQueryable<Person> x = _context.Persons;
var z = from tblPerson in _context.Persons
select tblPerson;
Are they all LINQ, just different flavours of it or is only z LINQ? If so what are the other 2 called? If they're all LINQ how to I differentiate between the three when Googling for information about them? With y and x should I be using var or IQueryable in MVC CORE (and why) and should I be using either over z?

Thanks to Jereon for the links. Wasn't sure if var or IQueryable was intrinsically linked to an implementation of LINQ or whether it was a more generic question. Generic it is.
From the links above this variety of LINQ
from tblPerson in _context.Persons
select tblPerson;
is referred to as either
query syntax
query expression
query comprehension syntax
while this variety of LINQ
db.Person = _context.Persons
.Include(px => px.Gender)
.Include(px => px.Title)
.Include(px => px.AddressIDs)
.ThenInclude(px => px.AddressType)
.Where(px => px.Name.Contains("foo")
.OrderBy(px => px.Name);
is referred to as either
extension method
method syntax
fluent syntax
As for usage, the general opinion seemed to be in two camps
use one or the other throughout your project
mix-and-match use query syntax for the following
when using the let keyword
when you have multiple generators (from clauses)
when doing joins
and extension method for everything else.

Related

What should you use for joining in LINQ, Query syntax or method syntax?

I would like to know in terms of performance is there any difference between using a query syntax or method syntax (Lambda expressions) for joining two entities?
I already know that in general there are no difference in terms of result, between query syntax and method syntax. However, for joining which of these are better to use performance wise?
Here is the sample code:
var queryResult = (from p in People
join i in Incomes
on p.PersonId equals i.PersonId
select new { p.PersonId, p.Name, p.Age, i.Amount }
).ToList();
var lambdaResult = People.Join(Incomes,
p => p.PersonId,
i => i.PersonId,
(p, i) => new { p.PersonId, p.Name, p.Age, i.Amount }).ToList();
I have already went through these websites but nothing has been mentioned for join
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq
LINQ - Query syntax vs method chains & lambda
There is no difference. Your first version (query language) is translated lexically into the second one (method syntax) before "real" compilation. The query language is only syntactic sugar and transformed into method calls. These calls are then compiled (if possible - the translation itself does not care about the correctness of the result, e.g. if People.Join even is valid C# and there is such a Join method in whatever People might be).
There maybe a difference in that this translation uses an explicit Select call instead of the resultSelector parameter of the Join method, but even that does not measurably impact performance.
This article by Jon Skeet helped me understand the transformation from query language to method syntax.
To answer the question "What should you use": this is really up to you. Consider:
what is more readable/understandable to you (and your co-workers!)
complex queries often are more readable in query syntax, the SQL-like style can be easier to read than a long chain of method calls
Note that every query syntax expression can be expressed as method calls, but not all method calls can be expressed in query syntax
mixing both syntaxes in a single query is often more confusing than sticking to one of them

Linq to NHibernate and Dynamic LINQ - query caching not working

I have problem with the NHibernate's second level cache. When I use query:
var items1 = Session.Query<Row>()
.Cacheable();
.Fetch(x => x.Field)
.OrderBy(x => x.Field.Value)
.ToList();
Everything is fine - the query is cached. But when I want to use Dynamic Linq (a link):
var items2 = Session.Query<Row>()
.Cacheable();
.Fetch(x => x.Field)
.OrderBy("Field.Value")
.ToList();
The query is not cached. Interesting thing is that, when I delete code line:
.Fetch(x => x.Field)
caching works again. So the problem is with using Fetch and dynamic linq OrderBy methods together.
EDIT:
When I try do debug NH code (QueryKey class), debugger tells me that these two queries do not have the same ResultTransformer (and deeper: a listTransformation private instance).
Any ideas?
Chris
Ok, I know what is the reason.
Dynamic Linq doesn't use Parameter Names in Linq Expressions. E.g. if I want to sort using lambda statemant, I write:
query.OrderBy(item => item.Name)
Above we see an item lambda parameter name.
When I use Dynamic linq:
query.OrderBy("Name")
in the result Queryable the lambda parameter in OrderBy mehod has no name (like item written above). We can illustrate the result like this:
query.OrderBy( => .Name)
And now, when NHibernate is decoding that Queryable expression and finds there an expression parameter that has no name, NH gives it a random name using GUID class. So every ordering using dynamic linq produces a Queryable Expression that has inconstant lambda parameter. This is the reason why NHibernate thinks that: query.OrderBy("Name") and query.OrderBy("Name") are not the same - they have another lamda parameters generated every time from scratch.
SOLUTION
If you want to fix it, you have to modify Dynamic Linq library.
In method ExpressionParser.ProcessParameters change line:
if (parameters.Length == 1 && String.IsNullOrEmpty(parameters[0].Name))
to:
if (parameters.Length == 1 && (parameters[0].Name == "it" || String.IsNullOrEmpty(parameters[0].Name)))
In method DynamicQueryable.OrderBy change line:
Expression.Parameter(source.ElementType, "")
to:
Expression.Parameter(source.ElementType, "it")
Now, query.OrderBy("Name") will produce query.OrderBy(it => it.Name).
Cheers!

use external function in LINQ

is it possible to use external function in linq select resault ?
and how to pass param to it?
sub x
Dim q = From a In contex Select New With {.z=z("MYNAME")}
end sub
function z(name as string)
return( name & "Something...")
end function
It depends upon the choosen provider. With normal LINQ over IEnumerable queries (a.k.a. LINQ to Objects) you can do. However, with most LINQ over Expression trees (such as LINQ to SQL, LINQ to Entities, NHibernate, LLBLGen, etc, etc) you can't. Those providers convert an expression tree to some other language, such as SQL, AD, SharePoint, etc, etc. They just don't know what to do with your custom method.
You can solve this in several ways. For instance, try to write the code of the method inline in the query. This way the provider knows what to do with it. Another option is to let the method call outside of the expression tree. For instance (sorry my C#):
var q = (from a in context select a).AsEnumerable();
// q is an IEnumerable and the z method will be called by .NET instead
// of being translated to SQL.
var q2 = (from a in q select new { z = z("MYNAME") };
That has been answered and explained here at StackOverflow. Please have a look.
And the complete explanation of what you are trying to do can be found here.

LINQ Query to find all tags?

I have an application that manages documents called Notes. Like a blog, Notes can be searched for matches against one or more Tags, which are contained in a Note.Tags collection property. A Tag has Name and ID properties, and matches are made against the ID. A user can specify multiple tags to match against, in which case a Note must contain all Tags specified to match.
I have a very complex LINQ query to perform a Note search, with extension methods and looping. Quite frankly, it has a real code smell to it. I want to rewrite the query with something much simpler. I know that if I made the Tag a simple string, I could use something like this:
var matchingNotes = from n in myNotes
where n.Tags.All(tag => searchTags.Contains(tag))
Can I do something that simple if my model uses a Tag object with an ID? What would the query look like. Could it be written in fluent syntax? what would that look like?
I believe you can find notes that have the relevant tags in a single LINQ expression:
IQueryable<Note> query = ... // top part of query
query = query.Where(note => searchTags.All(st =>
note.Tags.Any(notetag => notetag.Id == st.Id)));
Unfortunately there is no “fluent syntax” equivalent for All and Any, so the best you can do there is
query = from note in query
where searchTags.All(st =>
note.Tags.Any(notetag => notetag.Id == st.Id))
select note;
which is not that much better either.
For starters see my comment; I suspect the query is wrong anyway! I would simplifiy it, by simply enforcing separately that each tag exists:
IQueryable<Note> query = ... // top part of query
foreach(var tagId in searchTagIds) {
var tmpId = tagId; // modified closures...
query = query.Where(note => note.Tags.Any(t => t.Id == tmpId));
}
This should have the net effect of enforcing all the tags specified are present and accounted for.
Timwi's solution works in most dialects of LINQ, but not in Linq to Entities. I did find a single-statement LINQ query that works, courtesy of ReSharper. Basically, I wrote a foreach block to do the search, and ReSharper offered to convert the block to a LINQ statement--I had no idea it could do this.
I let ReSharper perform the conversion, and here is what it gave me:
return searchTags.Aggregate<Tag, IQueryable<Note>>(DataStore.ObjectContext.Notes, (current, tag) => current.Where(n => n.Tags.Any(t => t.Id == tag.Id)).OrderBy(n => n.Title));
I read my Notes collection from a database, using Entity Framework 4. DataStore is the custom class I use to manage my EF4 connection; it holds the EF4 ObjectContext as a property.

DynamicObject LINQ query does't works with custom class!

DynamicObject LINQ query with the List compiles fine:
List<string> list = new List<string>();
var query = (from dynamic d in list where d.FirstName == "John" select d);
With our own custom class that we use for the "usual" LINQ compiler reports the error "An expression tree may not contain a dynamic
operation":
DBclass db = new DBclass();
var query = (from dynamic d in db where d.FirstName == "John" select d);
What shall we add to handle DynamicObject LINQ?
Does DBClass implement IEnumerable? Perhaps there is a method on it you should be calling to return an IEnumerable collection?
You could add a type, against which to write the query.
I believe your problem is, that in the first expression, where you are using the List<>, everything is done in memory using IEnumerable & Link-to-Objects.
Apparently, your DBClass is an IQueryable using Linq-to-SQL. IQueryables use an expression tree to build an SQL statement to send to the database.
In other words, despite looking much alike, the two statements are doing radically different things, one of which is allowed & one which isn't. (Much in the way var y = x * 5; will either succeed or fail depending on if x is an int or a string).
Further, your first example may compile, but as far as I can tell, it will fail when you run it. That's not a particular good benchmark for success.
The only way I see this working is if the query using dynamic is made on IEnumerables using Link-to-Objects. (Load the full table into a List, and then query on the list)

Resources