I have a Expression Type variable. It has an expression to filter data.
For example, The expression lets SQL get data where LOCATION is 'KOR'.
{it => (it.LOCATION == "KOR")}
This expression will be the WHERE clause in a SQL statement.
Converting lambda expression to Sql queries looks complicated because there are many different expressions.
How can I achieve this purpose without starting from scratch?
Are there any nice libraries?
Added....
I can get a string of a lambda expression by invoking the ToString() method.
"it => (((it.LOCATION == \"KOR\") OrElse (it.LOCATION == \"FRA\")) AndAlso (it.Value > 30000))"
I'm not completely sure what you are asking for, but have you tried using Linq to Sql Dynamic Linq
Related
Select distinct Site
from Agency
where AgencyId= 1
how to convert this SQL query into Lambda expression.
If you mean the equivalent method syntax Linq corresponding to this SQL code (and given the little detail we have):
Agency.Where(a => a.AgencyId == 1).
Select(a => a.Site).
Distinct();
I built a Linq query on a MongoDB collection, which retrieves properly my docs:
var parts = mongoParts.AsQueryable()
.Where(mongo => mongo.Prop1 == bmbMatch.Prop1 && mongo.Prop2 == bmbMatch.Prop2)
.ToList();
This works fine, but to make this less code I wrote a Generic function taking a
Func<T, T, bool> selector
Which take the exact same lamdba expression as in Where clause above, which makes it:
var mongo = mongoQuery.AsQueryable()
.Where(tmongo => selector(tmongo, localMatch))
.ToList();
with selector as :
(mongo, local) => mongo.Prop1== local.Prop1 && mongo.Prop2 == local.Prop2
This gives me a "Unsupported where clause: "
Any ideas?
From the internet
Not all LINQ queries can be turned into equivalent MongoDB queries,
because C# allows you to write expressions that don't have any
equivalent in the MongoDB query language.
That being said, LINQ to MongoDB probably can't translate delegates.
You can find all supported LINQ queries on this address.
Conclusion: If you need to query very large data or make queries as fast as possible, you will have to stick with the former solution. Otherwise, pull all data from your db and query them in-memory.
This is my code:
string queryString = "Marco".ToLower();
utenti = db.User.Where(p =>
queryString.Contains(p.Nickname.ToLower()) ||
queryString.Contains(p.Nome.ToLower()) ||
queryString.Contains(p.Cognome.ToLower())).ToList();
but I get:
Only arguments that can be evaluated on the client are supported for the String.Contains method.
Why? Can't I use .Contains()?
Try .IndexOf. It is not LINQ that can't do Contains, it's LINQ to Entities and LINQ to SQL that can't.
string queryString = "Marco";
utenti = db.User.Where(p =>
queryString.IndexOf(p.Nickname, StringComparison.OrdinalIgnoreCase) >= 0 ||
queryString.IndexOf(p.Nome, StringComparison.OrdinalIgnoreCase) >= 0 ||
queryString.IndexOf(p.Cognom, StringComparison.OrdinalIgnoreCasee) >= 0)
.ToList();
Why?
LINQ uses deferred execution. This means it waits until you want to iterate over your query results before it does anything. There are 3 main types of LINQ:
LINQ to Objects - when your IEnumerable is already on the heap.
LINQ to Entities - when you want to query a database using Entity Framework.
LINQ to SQL - when you want to query a database using LINQ to SQL.
Deferred execution in the context of the second 2 means that your query is not executed on the database until you enumerate the results in a foreach block, or invoke an enumeration method like .ToList, .ToArray, etc. Until then, your query is just stored as expression trees in memory.
Your query would work just peachy if db.User was a collection in memory. However when the data is in a database, LINQ to Entities (or LINQ to SQL) must translate your expression trees to what it calls a "store expression" -- which is just fancy talk for "convert my LINQ expressions to SQL".
Now imagine you had a custom C# algorithm you wanted to use for your query, and you did something like this:
var result = db.User.Where(x => MyCustomMethod(x));
There is no way today that LINQ to Entities can convert your C# code into a SQL query (store expression). It is the same with a lot of other C# methods you rely on daily. It also does not support .ToLower, .ToUpper, .StartsWith, .EndsWith, etc. There is a limited number of C# methods that can be converted to store expressions, and .IndexOf just happens to be one of them.
However keep in mind that it is only the string object's Contains method that we are talking about here that is not supported for store expressions. LINQ to Entities does support .Contains on IEnumerables. The following is valid and will work with LINQ to Entities (not sure about LINQ to SQL):
var idsIWantToFind = new[] { 1, 2, 3 };
var users = db.Where(x => idsIWantToFind.Contains(x.UserId));
The above is the equivalent of doing a SQL WHERE UserId IN (1, 2, 3) predicate.
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.
I have functions that take SQL where clauses, and I'm wondering if there's a way to make them all strongly typed. Is there a way to take a lambda expression like a => a.AgencyID == id and convert it to a string where clause? Like "AgencyID = 'idValue'"?
Thanks!
You could turn the lambda function into an expression tree, and then traverse the tree to build your string.