代码之家  ›  专栏  ›  技术社区  ›  Tim Jarvis

使用C和fluent库动态构建Mongo查询

  •  1
  • Tim Jarvis  · 技术社区  · 6 年前

    我正在尝试建立一个mongo查询,我几乎让它在Linq中工作(95%在那里),但看起来Linq提供程序中有一个不幸的缺失功能,它相当于Intersect(coll).Any()或mongo术语Any in()

    我知道,如果将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 回复  |  直到 6 年前
        1
  •  1
  •   mickl    6 年前

    实际上,如果没有查询生成器和 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)));