2014-01-30 39 views
0

我無法使用動態生成的謂詞查詢MongoDB數據庫。MongoDB with C# - 使用動態生成的謂詞查詢

文件藥結構我試圖查詢的是:

{ 
    "_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 
} 

,我試圖用在產生一個運行時如謂詞查詢:

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) 

當我嘗試和執行該查詢我收到錯誤:「Unsupported where clause: <InvocationExpression>」。

我無法找到Linq to Mongo是否能夠從這樣的表達式生成查詢(我認爲它應該)。

所以我只是想做一些C#Mongo驅動程序不支持的東西,或者我沒有產生謂詞嗎?我從another question看到,我試圖做的事情應該是可能的(至少在理論上)。

我使用的是官方10gen的驅動程序版本1.8.3

+0

你可以嘗試.Tolist()不論.AsQueryable() –

+0

@RaphaëlAlthaus的我完全忘了AsExpandable()!它確實解決了這個問題。如果您將此作爲答案添加,我會接受它 – Anduril

回答

4

不知道它是mongodb的解決方案,但是您可以嘗試使用來自linqkit(由與PredicateBuilder相同的人員製作)的AsExpandable()

LinqKit(約AsExpandable()和關係與PredicateBuilder更多信息)可以發現here

+1

我可以確認它適用於MongoDb。如果你有一個形式爲'Expression >謂詞的謂詞;'然後你可以在C#中用'collection.AsQueryable ().AsExpandable()。查詢一個mongo集合where(predicate);' – Anduril

1

使用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); 

我改變了查詢中使用的$elemMatch,因爲我有你想要在相同的數組元素上匹配careerIdcultureId的感覺。如果該假設錯誤,請相應地調整查詢。

+0

謝謝您,我們正在做額外的工作,主要翻譯謂詞兩次 - 但我們希望堅持使用linq而不是將我們的查詢綁定到mongo以防我們希望在未來開關 – Anduril