带C#-动态生成谓词的MongoDB查询

带C#-动态生成谓词的MongoDB查询,c#,linq,mongodb,mongodb-.net-driver,C#,Linq,Mongodb,Mongodb .net Driver,使用动态生成的谓词查询MongoDB数据库时遇到问题 我试图查询的文档结构是: { "_id" : 3121 , "Active" : true , "CategoryId" : 1 , "Crci" : "IH" , "CultureId" : null , "DateUpdated" : { "$date" : 1381916923120 } , "Description" : "Na

使用动态生成的谓词查询MongoDB数据库时遇到问题

我试图查询的文档结构是:

{ 
    "_id" : 3121 , 
    "Active" : true , 
    "CategoryId" : 1 , 
    "Crci" : "IH" , 
    "CultureId" :  null  , 
    "DateUpdated" : { 
            "$date" : 1381916923120
    } , 
    "Description" : "National Careers Service: Actuary" , 
    "Keywords" : "" , 
    "MaxLevel" :  null  , 
    "MinLevel" :  null  , 
    "PhoneNumber" : "                    " , 
    "Priority" : 1 , 
    "Title" : "National Careers Service: Actuary" , 
    "WebUrl" : "https://nationalcareersservice.direct.gov.uk/advice/planning/jobprofiles/Pages/actuary.aspx" , 
    "CareerCultureExternalResources" : [ 
        { 
                "CareerId" : 5 , 
                "CultureId" : 1 , 
                "DisplayOrder" : 1 , 
                "ExternalResourceId" : 3121 , 
                "Vgs" :  null 
        }
    ] , 
    "SubjectExternalResources" : [ ] , 
    "LifestyleCategories" :  null
}
我尝试使用运行时生成的at谓词进行查询,例如:

Expression<Func<ExternalResourceView, bool>> predicate = predicateBuilder.True<ExternalResourceView>();
if (request.CultureId != null && request.CareerId != null) {
    predicate = predicate.And(er => er.CareerCultureExternalResources.Any(ccer => ccer.CareerId == request.CareerId.Value && ccer.CultureId == request.CultureId.Value));
} 
else if (request.SubjectAreaId != null && request.SubjectLevel != null && request.CultureId != null)
{
    predicate = predicate.And(er => er.SubjectExternalResources.Any(ser => ser.SubjectAreaId == request.CareerId && ser.CultureId == request.CultureId));
}
IEnumerable<ExternalResourceView> matchingExternalResources = _externalResourceLibrary.AsQueryable().Where(predicate)
Expression predicate=predicateBuilder.True();
if(request.CultureId!=null&&request.CareerId!=null){
谓词=谓词。和(er=>er.CareerCultureExternalResources.Any(ccer=>ccer.CareerId==request.CareerId.Value&&ccer.CultureId==request.CultureId.Value));
} 
else if(request.SubjectAreaId!=null&&request.SubjectLevel!=null&&request.CultureId!=null)
{
predicate=predicate.And(er=>er.SubjectExternalResources.Any(ser=>ser.SubjectAreaId==request.CareerId&&ser.CultureId==request.CultureId));
}
IEnumerable matchingExternalResources=\u externalResourceLibrary.AsQueryable()。其中(谓词)
当我尝试执行查询时,我得到错误:“
不支持的where子句:

我无法确定LINQtoMongo是否能够从这样的表达式生成查询(我认为应该)

那么,我只是想做一些C#Mongo驱动程序不支持的事情,还是我没有正确生成谓词?从这一点上,我看到我正在努力做的事情应该是可能的(至少在理论上)


我使用的是官方10gen驱动程序1.8.3版

使用MongoDB查询生成器,而不是将谓词翻译两次:

using MongoDB.Driver.Builders;
List<IMongoQuery> queries = new List<IMongoQuery>();
if (request.CultureId != null && request.CareerId != null) {
  queries.Add(
    Query<Person>.ElemMatch<IDependent>(p => p.Dependents,
      q => Query.And(
        q.EQ(x => x.CareerId, request.CareerId),
        q.EQ(x => x.CultureId, request.CultureId))));
}
// ... etc
// Final Query: 
var query = Query.And(queries);
使用MongoDB.Driver.Builders;
列表查询=新建列表();
if(request.CultureId!=null&&request.CareerId!=null){
查询。添加(
Query.ElemMatch(p=>p.依赖项,
q=>Query.And(
q、 等式(x=>x.CareerId,request.CareerId),
q、 EQ(x=>x.CultureId,request.CultureId));
}
// ... 等
//最后查询:
var query=query.And(查询);

我将查询更改为使用,因为我感觉您希望在同一数组元素上同时匹配
careerId
cultureId
。如果该假设错误,请相应地调整查询。

使用MongoDB查询生成器,而不是将谓词翻译两次:

using MongoDB.Driver.Builders;
List<IMongoQuery> queries = new List<IMongoQuery>();
if (request.CultureId != null && request.CareerId != null) {
  queries.Add(
    Query<Person>.ElemMatch<IDependent>(p => p.Dependents,
      q => Query.And(
        q.EQ(x => x.CareerId, request.CareerId),
        q.EQ(x => x.CultureId, request.CultureId))));
}
// ... etc
// Final Query: 
var query = Query.And(queries);
使用MongoDB.Driver.Builders;
列表查询=新建列表();
if(request.CultureId!=null&&request.CareerId!=null){
查询。添加(
Query.ElemMatch(p=>p.依赖项,
q=>Query.And(
q、 等式(x=>x.CareerId,request.CareerId),
q、 EQ(x=>x.CultureId,request.CultureId));
}
// ... 等
//最后查询:
var query=query.And(查询);

我将查询更改为使用,因为我感觉您希望在同一数组元素上同时匹配
careerId
cultureId
。如果这个假设是错误的,请相应地调整查询。

不确定这是mongodb的解决方案,但您是否可以尝试使用来自linqkit的
AsExpandable()
(与PredicateBuilder由同一人制作)


LinqKit(以及有关
AsExpandable()
PredicateBuilder
关系的更多信息)可以找到

不确定它是否是mongodb的解决方案,但您是否可以尝试使用来自LinqKit的
AsExpandable()
(与PredicateBuilder由同一人制作)


可以找到LinqKit(以及有关
AsExpandable()
以及与
PredicateBuilder
的关系的更多信息)

您可以尝试.Tolist(),而不考虑.AsQueryable()@RaphaëlAlthaus我完全忘记了AsExpandable()!它确实解决了问题。如果您将此添加为答案,我将接受。您可以尝试.Tolist(),而不考虑.AsQueryable()@RaphaëlAlthaus,因为我完全忘记了AsExpandable()!它确实解决了问题。如果你加上这个作为答案,我会接受的谢谢,你是对的,我们正在做额外的工作,主要是翻译谓词两次-但我们希望坚持使用linq,而不是将查询绑定到mongo,以防我们希望在未来切换。谢谢,您是对的,我们正在做额外的工作,主要是翻译谓词两次——但我们希望坚持使用linq,而不是将查询绑定到mongo,以防将来切换。我可以确认它对MongoDb有效。如果您有一个
表达式谓词形式的谓词
然后您可以通过
collection.AsQueryable().AsExpandable().Where(谓词)在C#中查询mongo集合
yes Expand对AndAlso表达式起作用,我可以确认它对MongoDb有效。如果您有一个
表达式谓词形式的谓词
然后您可以通过
collection.AsQueryable().AsExpandable().Where(谓词)在C#中查询mongo集合是扩展对AndAlso表达式起作用