B"H
C#sharps inclusion of linq right into the language is one of its most powerful features. It is also what makes Entity Framework such an enticing option for working with a database.
Unfortunately due to typing restrictions its often difficult to create centralized expressions to use throughout your project/solution.
One answer to that question is LinqKit. This was working great for me in EF 6.x. However when I moved to EF Core, I am facing a showstopper.
Instead of properly compiled expressions which should then be converted into SQL statement. What I am getting are function like expressions which don't include their sub expressions in the SQL that they generate. Instead they create AsyncLinqOperatorProvider.EnumerableAdapter
s which .Net tries to execute (out of an async context) when you access the IEnumerables
a few lines later.
So the question is: How do I get EF Core to execute the entire expression as one SQL statement and return a complete materialized object?
Given two classes
class OrderItemDTO
{
public string OrderItemName { get; set; }
}
class OrderDTO
{
public string OrderName { get; set; }
public ICollection<OrderItemDTO> OrderItems { get; set; }
}
I would like to create a global expressions somewhere
public static Expression<Func<Order, OrderDTO>> ToDTO = x => new OrderDTO
{
OrderName = x.Name,
OrderItems = x.Items.Select(y => new OrderItemDTO { OrderItemName = y.Name })
};
Which I would then use somewhere as var orders = await db.Orders.AsExpandable().Select(ToDTO).ToListAsync();
Expecting a fully materialized OrderDTO.
Instead what I get is a DTO with OrderItems as a AsyncLinqOperatorProvider.EnumerableAdapter
which causes a race condition when executed