I'm using EF Core 7. I want to perform server evaluation and project to a named tuple.
I tried:
var products = await _context.Products.Select(x => (x.Id, x.Name)).ToListAsync();
Which gives:
An expression tree may not contain a tuple literal.
I could do this with a regular tuple (Tuple.Create()) or an anonymous object (new {}), but I'd like to use a named tuple, if possible.
Can this be done somehow?
No, currently it is not possible because it is not possible to use value tuples in expression trees. You can monitor following issues/discussions at the github:
[Proposal]: Expression tree evolution
Expression trees support for tuples.
If you really-really want to use value tuples the only way is to map to them after the materialization of the query, but I would argue that it is rather pointless in most cases. Something like the following:
var products = (await _context.Products
.Select(x => new {x.Id, x.Name})
.ToListAsync())
.Select(ac => (ac.Id, ac.Name))
.ToList();
Related
I am writing an extension method which is meant to help prepare a LINQ query before it is actually executed in EF Core.
For example:
var context = new SchoolContext();
var studentWithGrade = context.Students
.Where(s => s.FirstName == "Bill")
.Include(s => s.Grade)
.Prepare()
.FirstOrDefault();
I am building the Prepare() extension on the IQueryable<> interface. In the method, I need to know things about the resulting query to be executed, such as:
The predicate (s.FirstName == "Bill")
The selected fields (from the Students table, as well as any fields from s.Grade)
The limit (an implied 1 in this case)
... and so on.
AFAICT, the Expression on the IQueryable is transformed into a SQL query (and executed) when FirstOrDefault() is called. So this transformation is obviously possible. But I would like to examine the data in a structured way, rather than inspecting a SQL query string. My hope was that I could simply inspect the queryable (query.Limit < 0) but the actual storage of these constraints seems buried with reflection in Expression object (?) based upon MethodCallExpression.cs's source code.
This question already has answers here:
Linq query or Lambda expression?
(5 answers)
Closed 7 years ago.
My project currently uses for following syntax for "linq"
var le = domainModel.EntityDataContext.Table_name_here.Query()
.WithFullReadCheck(domainModel.Security)
.Where(x => x.Metadata.AdvisorID == advisorId).FirstOrDefault();
It is said the above code is linq, being unaware about linq I decided to learn it. However, on https://msdn.microsoft.com/en-us/library/gg509017.aspx , things are pretty different.
what is being used in my code? Is it a version of linq? Is it something else?
What you are using is LINQ. There are 2 different notations you can use for writing LINQ - Lambda Syntax and Query Syntax
The difference is explained here: LINQ: Dot Notation vs Query Expression
There is more information on this on MSDN here: https://msdn.microsoft.com/en-us/library/bb308959.aspx
The MSDN articles starts explaining LINQ with SQL-like syntax ("query syntax") and then goes on to explain Lambda Expressions and Expression Trees ("lamba syntax").
That is extension method syntax for a query. The .Query().WithFullReadCheck() are much less common, but the rest .Where and .FirstOrDefault are pretty common query extensions. LINQ is a special syntax for expressing the same thing that can be done with chaining the query extension methods. Behind the scenes, they are identical.
See this question which gives an example of both LINQ and extension method syntax and has a good discussion of the differences between them: Extension methods syntax vs query syntax
Linq (language integrated query) is the language you use to query the data. You don't care where do they come from, that's the whole point of using it. You can use the same code to query arrays, collections, databases, xml files, directories, whatever... Linq translates your code in the background, so if you use it for instance to get the data from a database, it produces SQL to be sent to the database.
There are two syntax versions available:
1.) lambda syntax
2.) chainable methods
It doesn't matter which one you chose, just try to be consistent with it and use what makes you more comfortable / makes more sense in your situation.
LINQ is 'Language INtegrated Query'. In practical terms it means two things to most people:
The way that inline delegates are converted by the compiler into expression trees, not anonymous methods. That means that x => x.Metadata.AdvisorID == advisorId is not compiled into IL at compile time: instead it's compiled into code which builds an equivalent Expression object, which can be passed to a provider such as Entity Framework or LINQ to SQL, in order to generate a database query.
The other part it means to most people is the so-called "syntactic sugar", which effectively calls .Where(), .OrderBy() etc on your behalf:
from a in something
where a.Name == "Bob"
select a;
In both cases, the Queryable class in .NET provides extension methods for building a chain of Expression objects, for example .Where(), .OrderBy(), .Select() etc - these take an IQueryable (either untyped or with a generic parameter) and return another. They lightly wrap an Expression object at each point which represents the query as a whole.
Meaning:
someQueryable.Where(x => x.Id > 3).OrderBy(x => x.Date).Select(x => x.Ref)
Returns an object implementing IQueryable which holds an Expression which looks like:
Select(OrderBy(Where(someQueryable, x => x.Id > 3), x => x.Date), x => x.Ref)
... which is readable by LINQ providers to produce something like:
SELECT Ref FROM someTable WHERE Id > 3 ORDER BY Date
Finally, note that .Where(), .OrderBy() and the like are NOT limited to queryable/LINQ objects. They exist for IEnumerable (and IEnumerable<>), too - but this is not LINQ, and simply performs the operations at the instant that the method is called.
I'm trying to use predicates in my EF filtering code.
This works:
IQueryable<Customer> filtered = customers.Where(x => x.HasMoney && x.WantsProduct);
But this:
Predicate<T> hasMoney = x => x.HasMoney;
Predicate<T> wantsProduct = x => x.WantsProduct;
IQueryable<Customer> filtered = customers.Where(x => hasMoney(x) && wantsProduct(x));
fails at runtime:
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
I can't use the first option, as this is a simple example, and in reality, I'm trying to combine a bunch of predicates together (with and, not, or, etc.) to achieve what I want.
How can I get the EF Linq provider to "understand" my predicate(s)?
I get the same result if I use a Func<T, bool>. It works with an Expression<Func<T>>, but I can't combine expressions together for complex filtering. I'd prefer to avoid external libraries if possible.
UPDATE:
If this cannot be done, what options do I have? Perhaps expressions be combined / or'ed / and'ed somehow to achieve the same effect?
Expression<Func<Customer, bool>> hasMoney = x => x.HasMoney;
Expression<Func<Customer, bool>> wantsProduct = x => x.WantsProduct;
IQueryable<Customer> filtered = customers.Where(hasMoney).Where(wantsProduct);
Use Expression<T> to leave x => x.HasMoney as an expression tree, and not compile it to a .NET method
Use Expression<Func<Customer, bool>> rather than Expression<Predicate<Customer>>, because that's what Queryable.Where expects
Pass it directly in .Where, combining them using multiple .Where calls instead of &&.
It's possible to get more complex conditions (including not, or, etc.) working by rewriting them using .Union, .Except, etc.
An alternative is to use LINQKit's AsExpandable:
Expression<Func<Customer, bool>> hasMoney = x => x.HasMoney;
Expression<Func<Customer, bool>> wantsProduct = x => x.WantsProduct;
IQueryable<Customer> filtered = customers.AsExpandable().Where(x => hasMoney.Invoke(x) && wantsProduct.Invoke(x));
Unfortunately there's no way to use Predicate<T> in EF linq since it's impossible to map it on SQL query. This can be done with Expressions only because they can be parsed and converted to SQL.
In fact there are 4 language features that made linq possible:
Extension methods
Type inference
Closures
and for linq2sql especially
Expressions
UPDATE:
The possible solution is building expressions programmatically. How to: Use Expression Trees to Build Dynamic Queries
I am using Entity Framework 4.1 Code First and am also using the PredicateBuilder so that I can build predicate expressions across multiple Specification classes (using the Specification pattern). I am able to properly build a predicate and apply it to a DbSet, and the data I get is what I expect. However, no matter what I try, it's always lazy loading. This is a simple example of how I'm building the predicate and applying it.
IQueryable<HairColor> hairColorQuery = Context.Set<HairColor>().AsExpandable();
Expression<Func<Parent, bool>> parentPredicate = PredicateBuilder.And(PredicateBuilder.True<Parent>(), p => p.NameLast.StartsWith("V")).Expand();
Expression<Func<HairColor, bool>> hairColorPredicate = PredicateBuilder.And(PredicateBuilder.True<HairColor>(), h => h.Parents.AsQueryable().Any(parentPredicate));
HairColor[] hairColors = hairColorQuery.Where(hairColorPredicate).Include(h => h.Parents).ToArray();
Like I said above, I'm getting the data back that I want, but it ignores the Include.
Does anyone have any ideas?
Hi jumping in late on this, but had the same issue with using an extension Include method when using LinqKits predicate builder. The problem as referred to in the previous answer is that casting LinqKits ExpandableQuery to ObjectQuery (as required by the Include extension) results in null.
However found this link http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/ which is a Predicate builder which doesn't use AsExpandable to perform the search and hence the Include method can be used on it. Although the solution above also worked for me this different predicate builder allowed me to keep my code cleaner/more consistent
It's probably changing the query shape. Try this workaround
HairColor[] hairColors = hairColorQuery.Where(hairColorPredicate)
.Select(hc => new
{
HairColor = hc,
Parents = hc.Parents // eager load
})
.AsEnumerable()
.Select(hc => hc.HairColor);
I'm just getting started with EF and a query like the following strikes me as odd:
var departmentQuery =
schoolContext.Departments.Include("Courses").
OrderBy("it.Name");
Specifically, what sticks out to me is "it.Name." When I was tooling around with LINQ to SQL, pretty much every filter in a query-builder query could be specified with a lambda, like, in this case, d => d.Name.
I see that there are overrides of OrderBy that take lambdas that return an IOrderedQueryable or an IOrderedEnumable, but those obviously don't have the Execute method needed to get the ObjectResult that can then be databound.
It seems strange to me after all I've read about how lambdas make so much sense for this kind of stuff, and how they are translated into expression trees and then to a target language - why do I need to use "it.Name"?
I get lamdba expressions with mine; I can do Where (it.SomeProperty == 1)... do you have System.Linq as a namespace? You can try restructuring as:
var departmentQuery = from d in schoolContext.Departments.Include("Courses")
orderby d.Name
select d;
Those are some possibilities.
HTH.