Reputation: 1747
I have a [Flags] enum like this:
[Flags]
public enum Status
{
None = 0,
Active = 1,
Inactive = 2,
Unknown = 4
}
A Status enum may contain two values such as:
Status s = Status.Active | Status.Unknown;
Now I need to create a linq query (LINQ to ADO.NET Entities) and ask for records whose status is s above, 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 only knows to handle primitive types in the Where clause.
The error is:
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 may have a status Enum with 10 possible values and to query for 5 of the statuses. How do I construct the query using Flags enum in an elegant way?
Thanks.
Update
This seems to be a Linq to Entities problem. I think in LINQ to SQL it works (not sure, didn't tested).
Upvotes: 5
Views: 12546
Reputation: 11
In DB Flags enum must be integer. After that you can try it like this:
Status s = Status.Active | Status.Unknown;
var result = from r in db.Records
where (s & r.Status) == r.Status
select r
Upvotes: 1
Reputation: 5019
Just use HasFlag()
var result = from r in db.Records
where r.Status.HasFlag(s)
select r
Upvotes: 10
Reputation:
The folloiwng 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;
}
Upvotes: 0
Reputation: 36031
I am unsure if a bitwise AND-operation will work, but try casting s to an int:
int i = (int)s;
var result = from r in db.Records
select r
where (r.Status & i) == r.Status
Which database engine are you using? Possibly the engine does not support bitwise operations.
Upvotes: 0
Reputation: 269618
Try it like this:
byte status = (byte)(Status.Active | Status.Unknown);
var result = from r in db.Records
select r
where (r.Status & status) != 0
Upvotes: 0
Reputation: 34421
I don't know EF, but could inserting additional casts work?
var result = from r in db.Records
where ((byte)r.Status & (byte)s) == (byte)r.Status
select r
Upvotes: 0