I have an enum describing a certain sorting order for a post:
enum PostOrder
{
TitleAsc,
TitleDesc,
ScoreAsc,
ScoreDesc,
}
and an extension method to reuse the ordering logic:
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(),
};
}
The extension method works when used in a normal context but fails here:
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();
with this error:
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.
probably because it's being used in an Expression<>
context.
How can I make it work there?
A reproducible project can be found in this repository.