簡體   English   中英

"如何將變量傳遞給謂詞表達式?"

[英]How to pass a variable to predicate expression?

我正在動態創建Expression<Func<Entity, bool>>表達式樹:

int id = ...;
Expression<Func<Entity, int>> keySelector = e => e.Id;
BinaryExpression equals = Expression.Equal(
   keySelector.Body, 
   Expression.Constant(id, keySelector.Body.Type)); //replace this with a variable

var predicate = Expression.Lambda<Func<Entity, bool>>(equals, keySelector.Parameters[0]);

which produces equivalent of `e => e.Id == 1`.

How do I pass a variable instead of a constant: `e => e.Id == id`

您需要將 const 更改為可以更改以下屬性的內容:

class IDHolder
{
    public int Id { get; set; }
}

現在您將表達式綁定到 IDHolder 的實例,如下所示:

var idHolder = new IDHolder { Id = 0 };
Expression<Func<Entity, int>> keySelector = e => e.Id;

BinaryExpression equals = Expression.Equal(
    keySelector.Body,
           
    Expression.Property(
        Expression.Constant(idHolder, typeof(IDHolder)),
    nameof(IDHolder.Id))
           
    );

var predicate = Expression.Lambda<Func<Entity, bool>>(equals, keySelector.Parameters[0]);

謂詞變得稍微復雜一些,但沒有什么會使 EF 中斷:

x => x.Id == idHandler.Id

您可以通過編譯謂詞並運行更改 Id 和實體的簡單測試來對此進行測試:

var func = predicate.Compile();

idHolder.Id = 5;

Console.WriteLine(func(new Entity { Id = 0 }).ToString());  // false
Console.WriteLine(func(new Entity { Id = 5 }).ToString());  // true

idHolder.Id = 6;

Console.WriteLine(func(new Entity { Id = 6 }).ToString());   // true

請注意,這種方法不是線程安全的,如果您緩存謂詞和 idHolder 並在 web api 項目或任何可能同時使用此謂詞的任何東西中使用它,則會導致奇怪的行為。 要僅從請求中自動翻譯某些條件,最好在每次需要在 EF 中使用它時創建表達式。 創建表達式時沒有顯着的性能影響; 昂貴的操作是編譯,而 EF 從來沒有這樣做過。


或者也許我誤解了你的問題,你只需要一種方法來改變 id 的值,正如@Jochem Van Hespen 所建議的,你需要一個函數:

public Expression<Func<Entity,bool>> GetPredicate(int id){

    Expression<Func<Entity, int>> keySelector = e => e.Id;
    BinaryExpression equals = Expression.Equal(
       keySelector.Body, 
       Expression.Constant(id, keySelector.Body.Type)); 

    var predicate = Expression.Lambda<Func<Entity, bool>>(equals, keySelector.Parameters[0]);
    return predicate;
    }

你可以像這樣使用它:

 _dbContext.Set<Entity>().Where(GetPredicate(4))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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