Bitwise枚举(标志)查询使用MongoDB的官方C#驱动程序 [英] Bitwise enum (flags) query using MongoDB's official C# driver

查看:443
本文介绍了Bitwise枚举(标志)查询使用MongoDB的官方C#驱动程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试运行形式的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆