Bitwise enum (flags) query using MongoDB's official C# driver
bitwise-operators, c#, linq, mongodb, mongodb-.net-driver
Solution
My solution has two parts. I made a serializer for Enum flags that stores all the values in a list of strings. I made an extension method for Linq to "inject" the mongo query i need.
public static IQueryable<TItem> HasFlags<TItem, TProperty>(
this IQueryable<TItem> items,
Expression<Func<TItem, TProperty>> itemPropertyExpression,
params Enum[] enumFlags)
{
var enumFlagNames = enumFlags.Select(enumFlag => (BsonValue)enumFlag.ToString());
return items.Where(item => Query.In(ExtendedObject.GetPropertyName(itemPropertyExpression), enumFlagNames).Inject());
}
That way, its both readable and i don't need to deserialize all the objects into memory.
P.S: The GetPropertyName method is just a type safe way to get the property name:
public static string GetPropertyName<TClass, TProperty>(
Expression<Func<TClass, TProperty>> entityPropertyExpression)
{
return ((MemberExpression)entityPropertyExpression.Body).Member.Name;
}
Problem
When I try to run a LINQ query of the form: ``` MongoCollection<MyEntity> collection; collection.AsQueryable().Where(entity => (entity.Flags & MyFlags.AFlag) != MyFlags.None); ``` I get an `ArgumentException` with the message `Unsupported where clause: ((Int32)((Int32)entity.Flags & 4) != 0).` Is this a known bug/feature? Is there any workaround? From the documentation it seems like MongoDB has a bitwise update, but not a bitwise query. For comparison, the same query runs smoothly above Redis using ServiceStack as a client. I did find these two links (link1, link2) which suggest using JavaScript, however, that would make the implementation of the service layer very dependant on the DB technology.