LINQ to SQL: lambda expression vs .Where() [duplicate] - c#

This question already has answers here:
Extension methods syntax vs query syntax
(7 answers)
Closed 8 years ago.
Are
var movies = from m in db.Movies
select m;
movies = movies.Where(s => s.Title.Contains(searchString));
and
var movies = from m in db.Movies
where String.Equals(m.Title,searchString)
select m;
equivalent? And if so, why use one over the other? The syntax of the former seems more cryptic than the latter.

Behind the scenes, there's some translations going on.
For LINQ to SQL (and LINQ to Entities), the select keyword effectively ends a query. So, the second example has the filter as part of the SQL query, while the first one executes after the query.
There's a third way to do a LINQ query, called fluent syntax:
var movies = db.Movies.Where(s => s.Title.Contains(searchString));
If you look at the signature of Where, you'd find this:
IQueryable<T> Where(IQueryable<T> source, Expression<Func<T,bool>> predicate);
The key thing is the type of predicate: it's an expression of a (lambda) function, rather than merely a (lambda) function. This lets .Net dynamically convert the Expression object to SQL. For the query syntax, this parsing ends at select.

query expressions are compiled to method syntax by compiler when you compile the code,
whichever way you write code is a matter of preference, query expressions are preferred by developers from sql background.. :)

You're right, the latter form is more readable but sometimes you need the expression methods, like when you want to get the Count of result, and of course you can mix these two.

Related

Select query linq to sql function [duplicate]

Is it possible to use custom method In query for example:
var result = from u in context.MyTable where MyMethod(u) == 10 select u;
As Pranay explains, you cannot have a custom (C#) method as part of the LINQ to SQL query, because LINQ to SQL wouldn't be able to look at the expression tree of the method and so it cannot translate it to SQL.
One option that you have is to write your function in SQL and store it as a SQL function on the SQL Server (possibly, you could also use SQL CLR, but I have not tried that). Then you can add the function to your DataContext type and LINQ to SQL will translate it to calls to the function on SQL server. Something like:
var result = from u in context.MyTable
where context.MyMethod(u) == 10 select u;
The problem, of course, is that you'll need to write the function in SQL (I think SQL CLR could also work - not sure about the performance and other possible complications though)
I also wrote an article (some time ago) that shows how to do this when you write the "method" as an expression tree way (as a value of type Expression<Func<...>>), which is possible, because in this case, the code is compiled as an expression tree. However, there is some postprocessing that has to be done and you can still write just a single expression that can be easily inlined in the LINQ query.
Check this full article : What is and what isn't possible with linq
Following is not possible
// function used in filter
static bool MyFunc(Nwind.Product p)
{
return p.ProductName.StartsWith("B");
}
// query that uses MyFunc
var q =
from p in db.Products
where MyPriceFunc(p.UnitPrice) > 30m
select p
It compiles with no errors, but when you execute it LINQ to SQL throws an exception saying: "Static method System.Boolean MyTest(LINQTest.Nwind.Product) has no supported translation to SQL."
The exception is actually thrown when you try to fetch results from q (for example using the foreach statement), because LINQ to SQL attempts to convert the expression trees to T-SQL only when the results are needed and the query must be executed.
To fix the example you can simply copy the code that checks whether product name starts with "B" to the where clause of the query and it would work fine.
Yes, but if you are using Linq-to-Sql - your method has to have special code to handle to SQL conversion.

Generic Linq IN sub query expression

I am trying to find a way to create the Linq Expression tree for a sub-query in-clause.
SELECT * FROM x WHERE X.Id IN (SELECT XId FROM Y)
Say I have this query, I need a way to create the System.Linq.Expression of the where clause. I have a generic repository base solution for numerous Entities and I am creating the expression tree dynamically for other filters and I would like to add this to the already created expression tree.
I know I can do something like below, but it isn't generic enough.
var xIds = Y.Select(x => x.XId).ToList();
var final = X.Where(x => xIds.Contains(x.Id)).ToList();
But I need Expression tree that this would create.
I played around with this link: Creating a Linq expression dynamically containing a subquery and it doesn't seem to work. I might be missing something though, been staring at this for a while.
Thanks!

LINQ to Entities does not recognize the method 'Boolean ToBoolean [duplicate]

This question already has an answer here:
LINQ to Entities does not recognize the method 'System.Web.Mvc.FileResult'
(1 answer)
Closed 7 years ago.
I have a class Like this :
public class menu{
public string Permission{get;set;}
}
The value Of Permission is Encripted . I want all records where Permission is True. To do this, I use this query :
return
_menuSettings.Where(row => Convert.ToBoolean(Utilities.Encryption.Decrypt(row.Permission,"key"))==true).ToList();
but I get this error :
LINQ to Entities does not recognize the method 'Boolean ToBoolean(System.String)' method, and this method cannot be translated into a store expression.
I searched on google, but I can't solve it .
thanks
What you are asking for cannot be achieved by db query. I'm afraid you are stuck with in memory filtering (hope your don't have too many records) like this
return
_menuSettings.AsEnumerable().Where(...
here AsEnumerable() will switch the context from Linq to Entities to Linq to Objects
Not every method is convertible to SQL thats the essence of that message.
In your case you can compare against the string "true".
_menuSettings.Where(row => Utilities.Encryption.Decrypt(row.Permission,"key").ToLower()=="true").ToList();
Now as mentioned the message means the method is not convertible to SQL. So then by no real surprise get that Utilities.Encryption.Decrypt is also not supported.
Then continue with the same concept of taking things that don't work, out of the query.
The quick and dirty way is to realize/project the data (use ToList() or ToIEnumerable() before you filter with the non-supported filter).
Meaning that you take everything out of the table and filter it on your server instead on the DBMS (SQL server).
Like this. (i have split it into more lines for readability)
var projection = _menuSettings.ToList();
var result = projection.Where(row => Utilities.Encryption.Decrypt(row.Permission,"key").ToLower()=="true").ToList();
A wise choice is to find a good way to limit the projection size before you do heavy work like this.

How to filter and order collection in C#?

Here is the code:
public ActionResult Index()
{
var crView = db.CRCases.ToList();
return View(crView);
}
Would like to filter like we have in sql statement using WHERE and ORDER BY.
Is there any good reference on how to apply it?
linq is your friend here.
you can do
crView = crView.Where(x => x.yourPredicate).OrderBy( y => y.OrderClause);
CRCases should be a DBSet<T>. You can use LinQ like this :
db.CRCases.Where(x => x.TheProperty =xxx).ToList()
You can use LINQ = Language Integrated Query.
This have two different notations:
Functional: you can change several function calls beginning on an IEnumerable.
db.CrCases.Where(predicate).OrderBy(sortExpression)
"SQL like": it really looks like an "unordered SQL".
from crCase in db.CrCases where condition orderby sortExpression select crCase
The condition and sort expression in the first notation require lambda expressions (you can see them in action here). In the second case the condition is expressed.
Most of the queries can be written either way.
You'll usually use var to store the query, and materialize it later.
var query = from crCase in db.CrCases
where condition orderby sortExpression
select crCase
CrCase firstCase = query.Firts();
List<CrCase> cases = query.ToList();
There are several flavors of LINQ. They all look equal on the surface, but are translated into another thing. For example:
LINQ to objects: it's the more general, an allows to make queries on collections. Tis is what you'll use for this particular case.
LINQ to SQL: this allows to write queries in C# which are transalated to SQL queries in the underlying database
LINQ to Entities: similar to the previous, but you make your queries to an Entity Framework model, and the queries are finally transalated to the DB
There are some others flavors of LINQ. And, in fact, you can create your own, but that's not easy.
Finally, you have to take into account that a LINQ query isn't executed until you materialize it. I.e. it's not executed until you try to get data from it (converting it ToList(), ToArray() or whatever, enumerating it, or accesing any of it's data First(), Sum(), Count()). Depending on the flavor, the executing can be running C# code (LINQ to objects) or run a SQL Query in a DB (LINQ to SQL) or whatever.
Here you have a great place to learn how to use LINQ:
LINQ 101

Linq query or Lambda expression?

I'm using Entity Framework in my ASP.NET, C#, Web Application. If I need to select a record from DataBase (in Data Access Layer), which method should I use? Linq query or a Lambda Expression?
Eg:-
//Linq
var result = from a in db.myTable.Take(1) where a.Id == varId select a;
return result.First();
//Lambda
return db.myTable.FirstOrDefault(a => a.Id == varId);
Is there any preferred way in this scenario or any advantage over the other?
Query Expression compiles into Method Expression (Lambda expression), so there shouldn't be any difference, In your code though you are accessing First and FirstOrDefault which would behave differently.
See: Query Syntax and Method Syntax in LINQ (C#)
and LINQ Query Expressions (C# Programming Guide)
At compile time, query expressions are converted to Standard Query
Operator method calls according to the rules set forth in the C#
specification. Any query that can be expressed by using query syntax
can also be expressed by using method syntax. However, in most cases
query syntax is more readable and concise.
Linq query syntax is just a syntax sugar for expression methods. Any Linq query compiled into expression methods. Btw your first query:
var query = from a in db.myTable.Take(1)
where a.Id == varId
select a;
return query.First();
Is equivalent to
return db.myTable.Take(1).Where(a => a.Id == varId).First();
Both of your tries use Linq.
The first takes one record and checks if the id matches.
The second takes the first record where the id matches.
That's a difference.
Every query expression can be expressed as C#-code using calls to query operators as extension methods. But the opposite is not true; only a small subset of the standard query operators can be used as keywords in query expressions. In other words query expressions have some limitations that the method-call mechanism does not have:
Some query operators have simply no C# query expression equivalent, e.g. ToArray().
We can't use all kinds of overloads in C#'s query expressions. E.g. there is an overload of Select() that awaits the index of the currently iterated object; you cannot call this overload within a query expression.
We can't use statement lambdas in query expressions. - This is the cause why object and collection initializers have been introduced into the C# language.
I guess the result is the same. Lambda is just a bit more comfortable.
If you need a result of just one table, the lambda expression is very fast and readable.

Categories