[英]How to optimize this LINQ expression w/ Where condition and calling Method?
[英]Dynamically build an expression for calling the LINQ Where method
我正在使用書中的一些代碼來實現用於EF數據訪問的通用存儲庫類。 該代碼使用以下兩種方法通過其int id
主鍵獲取單個實體,假設所有DB對象都具有一個int PK。 但是,我使用的主要是自然鍵的導入數據庫,並且希望保留所有FK關系,即我不希望將數據庫重新設計為使用單列int PK。
如何修改下面的代碼以使用多列鍵?
protected Expression<Func<T, bool>> CreateGetExpression<T>(int id)
{
ParameterExpression e = Expression.Parameter(typeof(T), "e");
PropertyInfo propInfo = typeof(T).GetProperty(KeyPropertyName);
MemberExpression m = Expression.MakeMemberAccess(e, propInfo);
ConstantExpression c = Expression.Constant(id, typeof(int));
BinaryExpression b = Expression.Equal(m, c);
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(b, e);
return lambda;
}
public override T Get<T>(int id)
{
return List<T>().FirstOrDefault(CreateGetExpression<T>(id));
}
我希望我的Get
方法看起來像這樣:
public override T Get<T>(params object[] keyValues)
{
return List<T>().FirstOrDefault(CreateGetExpression<T>(keyValues));
}
好吧,您基本上需要使用多個相等性檢查來構建表達式樹。 您可以采用構建單個相等性檢查所需的代碼,也可以構建多個代碼,每個鍵一次。 然后,您需要使用Expression.AndAlso
多次結合它們-因此,如果您具有單獨的相等性檢查e1
, e2
和e3
,則可以使用:
var e = Expression.AndAlso(Expression.AndAlso(e1, e2), e3);
需要注意的一件事:您需要對整個最終表達式使用單個 ParameterExpression
因此,您需要調整“構建單個檢查”方法以將ParameterExpression
用作參數...並且您不需要直到最后都需要使用Expression.Lambda
。 因此,總體步驟如下所示:
ParameterExpression
Expression.Equals
創建一個BinaryExpression
,並使用剛剛創建的相同ParameterExpression
。 Expression.AndAlso
多次調用結合在一起 Expression.Lambda
創建一個Expression<Func<T, bool>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.