場景 最近對爬蟲的數據庫架構做調整,需要將數據遷移到MongoDB上去,需要重新實現一個針對MongoDB的Dao泛型類,好吧,動手開工,當實現刪除操作的時候問題來了。 我們的刪除操作定義如下:void Delete(TEntity entity)。TEntity是我們的泛型類。 而MongoDB官方驅動自帶的刪除操作是這樣的: // 假設數據模型為已定義的Article var query = Query<Article>.EQ(t => t.Id, id); coll.Remove(query); Dao操作的接口是不能修改的,這就要求我們必須實現以下操作: 獲取entity的Id值 構造lambda表達式用於獲取Id屬性 實現 對於第1個好辦,直接通過反射拿就可以了,至於第2個構造lambda表達式卻不知該如何下手了。 在網上查資料了解到C# Lambda表達式樹允許我們像處理數據(比如讀取,修改)一樣來處理Lambda表達式。。這就有方向了,研究了一下表達式樹的相關知識,歷經坎坷終於將其實現。 我用到的lambda表達式比較簡單,也容易構造,代碼中看注釋應該就明白了,代碼: /// <summary> /// 因為使用的Mongodb,每個數據模型必定包含Id屬性,通過Id屬性來刪除實體 /// </summary> /// <param name="entity"></param> public void Delete(TEntity entity) { var coll = _db.GetCollection<TEntity>(typeof(TEntity).Name); if (entity == null) { return; } ObjectId id = (ObjectId)typeof(TEntity).GetProperty("Id").GetValue(entity, null); // 通過表達式樹構造lambda表達式{t => t.Id} // 構造調用目標t var target = Expression.Parameter(typeof(TEntity), "t"); // 構造對t的屬性Id的表達式 MemberExpression bodyExp = Expression.Property( target, "Id"); // 構造完整的lambda表達式 Expression<Func<TEntity, ObjectId>> selector = Expression.Lambda<Func<TEntity, ObjectId>>(bodyExp, new [] { target }); // 使用泛型前的語句: Query<Article>.EQ(t => t.Id, id); var query = Query<TEntity>.EQ(selector, id); coll.Remove(query); }