【发布时间】:2020-11-02 07:00:13
【问题描述】:
我有一个枚举来描述帖子的特定排序顺序:
enum PostOrder
{
TitleAsc,
TitleDesc,
ScoreAsc,
ScoreDesc,
}
以及重用排序逻辑的扩展方法:
static class IQueryableExtensions
{
public static IOrderedQueryable<Post> OrderByCommon(this IQueryable<Post> queryable, PostOrder orderBy)
=> orderBy switch
{
PostOrder.TitleAsc => queryable.OrderBy(x => x.Title),
PostOrder.TitleDesc => queryable.OrderByDescending(x => x.Title),
PostOrder.ScoreAsc => queryable.OrderBy(x => x.Score).ThenBy(x => x.Title),
PostOrder.ScoreDesc => queryable.OrderByDescending(x => x.Score).ThenBy(x => x.Title),
_ => throw new NotSupportedException(),
};
}
扩展方法在正常上下文中使用时有效,但在此处失败:
var input = PostOrder.ScoreDesc;
var dbContext = new QuestionContext();
var users = dbContext.Users
.Select(x => new
{
User = x,
Top3Posts = x.Posts.AsQueryable()
.OrderByCommon(input)
.Take(3)
.ToList()
}).ToList();
出现此错误:
The LINQ expression 'MaterializeCollectionNavigation(
Navigation: User.Posts,
subquery: NavigationExpansionExpression
Source: DbSet<Post>()
.Where(p => EF.Property<Nullable<int>>(u, "Id") != null && object.Equals(
objA: (object)EF.Property<Nullable<int>>(u, "Id"),
objB: (object)EF.Property<Nullable<int>>(p, "AuthorId")))
PendingSelector: p => NavigationTreeExpression
Value: EntityReference: Post
Expression: p
.Where(i => EF.Property<Nullable<int>>(NavigationTreeExpression
Value: EntityReference: User
Expression: u, "Id") != null && object.Equals(
objA: (object)EF.Property<Nullable<int>>(NavigationTreeExpression
Value: EntityReference: User
Expression: u, "Id"),
objB: (object)EF.Property<Nullable<int>>(i, "AuthorId")))
.AsQueryable()
.OrderByCommon(__input_0)
.Take(3)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
可能是因为它在 Expression<> 上下文中使用。
我怎样才能让它在那里工作?
可以在in this repository找到一个可重现的项目。
【问题讨论】:
-
你能详细说明一下这个错误吗?
-
如果您更改
OrderBy扩展方法,使其不执行任何操作,只返回可查询的输入,您会得到相同的错误吗?如果它只返回queryable.Where(x => x.Title)?如果它们都有效,那么这就是你对枚举所做的事情。您可以编辑问题并向我们展示您在扩展方法中所做的相关部分吗? -
我在移动 ATM 上,稍后我将使用该代码编辑问题,但 Entity.Entities 属性只是一个实体列表。这是一个延迟加载的导航属性。我相信,根本问题在于,除非您告诉 EF Core 如何翻译您的自定义扩展函数,否则它不知道如何翻译。这在表达式上下文之外无关紧要,但在表达式上下文中很重要,其中所有内容都必须可转换为 SQL。
-
@Shoe 这意味着代码的重要部分丢失了——
...和something here后面的任何内容。OrderBy(x => x.Title)可以毫无问题地翻译,所以你的代码肯定在做一些更复杂的事情 -
@PanagiotisKanavos 我改进了问题并添加了一个可重现的项目。
标签: c# linq entity-framework-core npgsql .net-5