Reputation: 2419
I am trying to write an elegant solution to filter a value against multiple Enum values in an IQueryable. Here's what I have got so far:
Extension
public static class EnumExtensions
{
public static bool IsAny<T>(this T value, params T[] choices)
where T : Enum
{
return choices.Contains(value);
}
}
Usage
query = query.Where(x => x.Status.IsAny(OrderStatus.Accepted, OrderStatus.Received, OrderStatus.Approved));
But when I execute this, I get following error:
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The LINQ expression 'DbSet<SalesOrder>
.Where(s => s.DeletedAt == null)
.Where(s => False || s.SellerId == __request_OwnerId_0)
.Where(s => s.Status
.IsAny(OrderStatus[] { Accepted, Received, Approved, }))' 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.
Any pointers on how I can get this working?
Upvotes: 0
Views: 545
Reputation: 155270
You cannot use custom methods inside Linq queries and in Expression<>
params for EF. You will need to do it the long-form way:
query = query
.Where( x =>
x.Status == OrderStatus.Accepted ||
x.Status == OrderStatus.Received ||
x.Status == OrderStatus.Approved
);
Depending on your RDBMS, you might be able to do it this way though:
static readonly OrderStatus[] _these = new[] { OrderStatus.Accepted, OrderStatus.Received, OrderStatus.Approved };
// ...
query = query.Where( x => _these.Contains( x.Status ) );
...which should be translated to this SQL:
WHERE
x.Status IN ( 0, 1, 2 )
(Assuming OrderStatus.Accepted == 0
, Received == 1
, Approved == 2
).
Upvotes: 3