2014-01-10 109 views
1

用例: PHP symfony項目,它必須與C#後端與Mongo進行通信。在PHP前端中,可以通過查詢從Mongo獲取數據。該查詢通過API(XML)發送。 C#後端將此XML反序列化以獲取對象。然後我想在我的記憶中執行一個Linq-to-objects查詢(這是通過API發送的查詢)。所以我想製作我自己的「LinqBuilder」,這樣我就可以查詢這些對象並將它們返回到我的PHP前端。數組屬性上的Lambda表達式

我有以下對象:

public class MongoDoc 
{ 
    public int Id { get; set; } 
    public string Kind { get; set; } 
    public BsonDocument Data { get; set; } 
} 

下面是我想要實現的例子。

var list = source.Where(x => x.Data["Identifier"] == "H7PXXK").ToList(); // source is collection of MongoDoc objects 

上面的代碼行是我想用表達式構建的,因爲它必須是動態的。我過去的成績是查詢我MongoDoc對象的「類」屬性如下:

ParameterExpression _expr = Expression.Parameter(typeof(MongoDoc), "x");  
expression = Expression.Equal(
    Expression.PropertyOrField(_expr, "Kind"), 
    Expression.Constant("KindValue") 
); 

這將產生以下lamdba:

x => (x.Kind == "KindValue") 

這是正確的,但現在我需要得到BsonDocument屬性Data中的屬性Identifier。通常情況下,它會像上面那樣:x => x.Data["Identifier"] == "Value"。這正是我的問題所在。我怎樣才能做到這一點?

回答

0

認爲它應該是這樣的。

var _expr = Expression.Parameter(typeof(MongoDoc), "x"); 

//x.Data 
Expression member = Expression.PropertyOrField(_expr, "Data"); 

//x.Data["Identifier"] 
member = Expression.Property(member, "Item", new Expression[]{Expression.Constant("Identifier")}); 

//x.Data["Identifier"] == "H7PXXK" 
member = Expression.Equal(member, Expression.Constant((BsonValue)"H7PXXK")); 

編輯:

從您的評論,應該是

//x.Data["MoreData"] 
member = Expression.Property(member, "Item", new Expression[]{Expression.Constant("MoreData")}); 
//x.Data["MoreData"]["Identifier"] 
member = Expression.Property(member, "Item", new Expression[]{Expression.Constant("Identifier")}); 
+0

謝謝!這正是我所期待的。我只需要添加一個強制轉換爲BsonValue,因爲x.Data [「Identifier」]是BsonValue類型。否則你會得到這個異常:「二進制運算符Equal沒有爲'MongoDB.Bson.BsonValue'和'System.String'類型定義。」 – DeluxZ

+0

接下來是如果Data屬性具有另一個BsonDocument作爲屬性,所以您需要類似x.Data [「MoreData」] [「Identifier」] – DeluxZ

+0

@DeluxZ爲下一個起見,請參閱編輯(轉換也失蹤)。 –