EFCore 编译查询不能使用 orderby linq 语句

问题描述 投票:0回答:1

当我尝试编译这个测试代码时:

using Microsoft.EntityFrameworkCore;

using var db = new InventoryContext();
await db.AddAsync<Item>(new() { Name = "Table", Description = "A wooden office Table with a cup holder", Type = ItemType.Furniture });
await db.SaveChangesAsync();

Console.WriteLine("Showing all entries:");

Func<InventoryContext, IAsyncEnumerable<Item>> compiled = EF.CompileAsyncQuery((InventoryContext db) => from item in db.Items orderby item.Id select item);

IAsyncEnumerable<Item> items = compiled(db);

await foreach (Item item in items)
{
    Console.WriteLine(item.Id);
    Console.WriteLine(item.Name);
    Console.WriteLine(item.Type);
    Console.WriteLine(item.Description is null ? "*no description*" : item.Description);
    Console.WriteLine();
}

它告诉我“System.Func>>”不能隐式转换为“System.Func>”

将第 10 行更改为

Func<InventoryContext, IAsyncEnumerable<Item>> compiled = EF.CompileAsyncQuery((InventoryContext db) => db.Items.OrderBy(x => x.Id));

它也不会起作用,只有在添加 .Select(x=>x) 或删除 orderby 部分时它才会起作用。有人可以解释为什么(至少对我来说是这样)有序语句不能用于编译查询吗?

c# .net entity-framework entity-framework-core
1个回答
1
投票

您遇到的问题与查询表达式返回的类型有关。当你在查询中使用 orderby 时,它返回一个 IOrderedQueryable,它不直接与 IAsyncEnumerable 兼容。

但是,当你使用.OrderBy(x => x.Id)然后添加.Select(x => x)或者去掉orderby部分时,返回类型变为IQueryable,兼容IAsyncEnumerable。这就是为什么在这些情况下你不会收到类型不匹配错误的原因。

要解决此问题并在已编译查询中使用 orderby 部分,您可以像这样简单地将结果转换为 IQueryable:

Func<InventoryContext, IAsyncEnumerable<Item>> compiled = EF.CompileAsyncQuery((InventoryContext db) =>
(from item in db.Items orderby item.Id select item) as IQueryable<Item>);

或者,使用方法语法:

Func<InventoryContext, IAsyncEnumerable<Item>> compiled = EF.CompileAsyncQuery((InventoryContext db) =>
    db.Items.OrderBy(x => x.Id) as IQueryable<Item>);

这将允许您在编译查询中保留 orderby 部分,而不会遇到类型不匹配错误。

© www.soinside.com 2019 - 2024. All rights reserved.