How to use flags in Linq to Entities queries?

I have an enumeration of [Flags] as follows:

[Flags] public enum Status { None = 0, Active = 1, Inactive = 2, Unknown = 4 } 

The state list can contain two values, for example:

 Status s = Status.Active | Status.Unknown; 

Now I need to create a linq query (LINQ to ADO.NET Entities) and query for records whose status is higher, that is, Active or Unknown;

 var result = from r in db.Records select r where (r.Status & (byte)s) == r.Status 

Of course, I get an error because LINQ to Entities knows how to handle primitive types in the Where clause.

Error:

Unable to create a constant value of type "Closure Type". Only primitive types (such as Int32, String, and Guid ') are supported in this context.

Is there a workable way? I can have an Enum status with 10 possible values โ€‹โ€‹and request 5 statuses. How can I build a query using flag renaming in an elegant way?

Thanks.

Update

This seems to be a Linq to Entities issue. I think it works in LINQ to SQL (not sure, not tested).

+4
source share
8 answers

Just use HasFlag()

 var result = from r in db.Records where r.Status.HasFlag(s) select r 
+5
source

Take a look at the following good post, it shows you the following alternatives:

  • At least one of the selected flags is set.
  • Exactly the same flags set.
  • At least the flags you selected, and more

https://timdams.wordpress.com/2011/02/14/using-enum-flags-to-write-filters-in-linq/#comment-30

+2
source
 var result = from r in db.Records where r.Status == s select r 
+1
source

I do not know EF, but can it add additional roles?

 var result = from r in db.Records where ((byte)r.Status & (byte)s) == (byte)r.Status select r 
0
source

Try the following:

 byte status = (byte)(Status.Active | Status.Unknown); var result = from r in db.Records select r where (r.Status & status) != 0 
0
source

I'm not sure if the bitwise AND operation works, but try making s in int:

  int i = (int)s; var result = from r in db.Records select r where (r.Status & i) == r.Status 

What database engine are you using? The engine may not support bitwise operations.

Link: http://www.matthidinger.com/archive/2008/02/26/entity-framework-comparison-frustration-explained.aspx

0
source

The following works for me in C #

  public const StatusTypes ActiveAlert = StatusTypes.Accepted | StatusTypes.Delivered; int flags = (int)ActiveAlert; try { var query = from p in model.AlertsHistory where (p.UserId == clientId && (p.Status.HasValue && (p.Status.Value & flags) != 0)) select p; var aList = query.ToList(); return (aList); } catch (Exception exc) { log.Error("Exception getting Alerts History for user.", exc); throw; } 
0
source

In DB Flags, the enumeration must be an integer. After that, you can try it as follows:

 Status s = Status.Active | Status.Unknown; var result = from r in db.Records where (s & r.Status) == r.Status select r 
0
source

All Articles