Bitwise枚举(标志)查询使用MongoDB的官方C#驱动程序 [英] Bitwise enum (flags) query using MongoDB's official C# driver
问题描述
当我尝试运行形式的LINQ查询:
<预类=郎-CS prettyprint-覆盖>
MongoCollection< myEntity所>采集;
collection.AsQueryable(),其中(实体=>
(entity.Flags&安培;!MyFlags.AFlag)= MyFlags.None)。
我得到一个的ArgumentException
的消息不支持的where子句:(!(Int32)已((Int32)已entity.Flags及4)= 0)
这是一个已知的bug /功能吗?
有没有什么解决方法吗?
从文档好像MongoDB中有一个逐位更新,但不是逐位查询。
为了比较,相同的查询运行顺利使用ServiceStack作为客户端的Redis以上
我发现这两个环节(的 LINK1 ,链接2 )使用JavaScript,但是,这将使服务层非常依赖于数据库技术的实现,它建议。
我的解决方案有两个部分。
我为枚举标志串行器将信息存储在一个字符串列表所有的值。
我做对LINQ的扩展方法注入蒙戈查询我需要
公共静态的IQueryable< TItem> ; HasFlags< TItem,TProperty>(
本的IQueryable< TItem>的项目,
表达式来; Func键< TItem,TProperty>> itemPropertyExpression,
PARAMS枚举[] enumFlags)
{
变种enumFlagNames = enumFlags.Select(enumFlag = GT;(BsonValue)enumFlag.ToString());
返回items.Where(项目=> Query.In(ExtendedObject.GetPropertyName(itemPropertyExpression),enumFlagNames).Inject());
}
这样的话,它可以读取和我不需要反序列化的所有。对象到内存
PS:本getPropertyName方法方法仅仅是一种安全的方式来获得属性名称:
公共静态字符串getPropertyName方法< TClass,TProperty>(
表达式来; Func键< TClass,TProperty>> entityPropertyExpression)
{
回报率((MemberExpression) entityPropertyExpression.Body).Member.Name;
}
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.
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;
}
这篇关于Bitwise枚举(标志)查询使用MongoDB的官方C#驱动程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!