簡體   English   中英

動態構建用於調用LINQ Where方法的表達式

[英]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多次結合它們-因此,如果您具有單獨的相等性檢查e1e2e3 ,則可以使用:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM