使用C#和流畅的库动态构建Mongo查询

时间:2018-08-23 04:43:02

标签: c# mongodb linq fluent

我正在尝试建立一个mongo查询,我几乎可以在Linq中使用它(那里有95%),但是似乎Linq提供程序中缺少一种等效于Intersect(coll ).Any()或用Mongo的话说AnyIn()

我知道,如果我将fluent库与一些构建器一起使用,我可以构建一个过滤器,该过滤器将为我提供AnyIn()-但是我所缺少的是如何构建整个查询,初始过滤器,聚合,投影和最后的过滤器?

这与我的Linq查询非常接近-只要我不尝试在过滤器中比较集合成员身份,此功能就可以按要求工作

public List<MyResult> ListMyResults(Expression<Func<MyResult, bool>> filter, int skip, int take)
{
    // Limit to tennants on main Entity being queried
    var ents = ApplyDataRestrictions(db.GetCollection<Entity>("entities").AsQueryAble());
    var children = db.GetCollection<Child>("children").AsQueryable();
    var chickens = db.GetCollection<Chicken>("chickens").AsQueryable();

    // Join a couple collections for their counts
    var result = from ent in ents   
                join c in children on ent.Id equals c.EntityId into kids
                join ck in chickens on ent.Id equals ck.EntityId into birds
                // Project the results into a MyResult
                select new MyResult
                {
                    Id = ent.Id,
                    AProperty = ent.AProperty,
                    SomeCollection = ent.SomeCollection,
                    SomeOtherCollectionTagsMaybe = ent.SomeOtherCollectionTagsMaybe,
                    TotalKids = kids.Count(),
                    TotalChickens = birds.Count() 
                };
    if(filter != null)
    {
        // Apply the filter that was built up from criteria on the MyResults data shape
        result = result.Where(filter);
    }

    result = result.Skip(skip).Take(take);
    return result.ToList()
}

public IQueryable<Entity> ApplyDataRestrictions(IQueryable<Entity> query)
{
    ... restrict results to only those with my tennant id ...
}

1 个答案:

答案 0 :(得分:1)

实际上,没有Query Builder和AnyIn也可以实现相同的行为。拥有IQueryable接口后,您可以尝试使用.Any()作为内部谓词的Contains()

var inMemoryList = new List<int>() { 3, 4, 5 };

var q = from doc in Col.AsQueryable()
        where doc.Collection.Any(x => inMemoryList.Contains(x))
        select doc;

var q2 = Col.AsQueryable().Where(x => x.Collection.Any(y => inMemoryList.Contains(y)));