Description
Update
Modifying the description to track support for AsQueryable
in linq queries.
AsQueryable
method is required when user wants to pass Expression to linq method which is hanging of an navigation property since navigation is of type IEnumerable. With the relinq fix now we can get parsed query with AsQueryable but we are client eval-ing afterwards. This issue is to track work needed on EF Core side to translate query to server.
Query
var query3 = db.Products.Select(p => p.ProductCategories.AsQueryable().Select(pc => pc.Category).Where(Category.IsGenre)).ToList();
QueryExecution:
dbug: Microsoft.EntityFrameworkCore.Query[10104]
Optimized query model:
'from Product p in DbSet<Product>
select
from ProductCategory pc in
(from ProductCategory <generated>_1 in DbSet<ProductCategory>
where Property([p], "ProductId") ?= Property([<generated>_1], "ProductId")
select [<generated>_1]).AsQueryable()
join Category pc.Category in DbSet<Category>
on Property([pc], "CategoryId") equals Property([pc.Category], "CategoryId")
where [pc.Category].ParentId == (Nullable<Guid>)__Genre_0
select [pc.Category]'
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'join Category pc.Category in value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[EFSampleApp.Category]) on Property([pc], "CategoryId") equals Property([pc.Category], "CategoryId")' could not be translated and will be evaluated locally.
warn: Microsoft.EntityFrameworkCore.Query[20500]
The LINQ expression 'where ([pc.Category].ParentId == Convert(__Genre_0, Nullable`1))' could not be translated and will be evaluated locally.
dbug: Microsoft.EntityFrameworkCore.Query[10107]
(QueryContext queryContext) => IEnumerable<IOrderedQueryable<Category>> _InterceptExceptions(
source: IEnumerable<IOrderedQueryable<Category>> _ShapedQuery(
queryContext: queryContext,
shaperCommandContext: SelectExpression:
SELECT [p].[ProductId]
FROM [Commerce].[Product] AS [p],
shaper: TypedProjectionShaper<ValueBufferShaper, ValueBuffer, IOrderedQueryable<Category>>),
contextType: EFSampleApp.MyContext,
logger: DiagnosticsLogger<Query>,
queryContext: queryContext)
Original Issue
Hi!
I'm trying to map an existing database to EF Core. Our project has a terrible model where we have to compare the ParentId
to a specific Guid
to find out the type of a row. E.g. we have the table Categories
and each Guid identifies Genre
, Mood
, etc. (we have a music app).
So I'm trying to write this property in the Category class, but if I do, I'm unable to use Include
because it can't be translated:
public virtual bool IsGenre => ParentId == Genre;
private static Guid Genre = Guid.Parse("3CA9FA61-EB62-4480-B476-867F78A9ADB3")
If I instead do ctx.Categories.Where(c => c.ParentId == Guid.Parse("3CA9FA61-EB62-4480-B476-867F78A9ADB3")
it works perfectly.
I'm wondering if there's any way to move this to the Category class so I can avoid copy and pasting for each query I need to write.
I tried to manually create the Expression
:
public static Expression<Func<Category, bool>> IsGenre = c => c.ParentId == Genre;
but I get the following error on p.ProductCategories.Select(pc => pc.Category).Where(Category.IsGenre)
:
Error CS1929 'IEnumerable<Category>' does not contain a definition for 'Where' and the best extension method overload 'Queryable.Where<Category>(IQueryable<Category>, Expression<Func<Category, bool>>)' requires a receiver of type 'IQueryable<Category>'
With .AsQueryable()
I'm able to compile the program but I get This overload of the method 'System.Linq.Queryable.AsQueryable' is currently not supported
.
Thanks!