簡體   English   中英

動態構建表達式樹

[英]Dynamically building an expression tree

我正在關注這個優秀的例子: 將Linq轉換為Sql表達式到表達式樹

在我的情況下,我正在嘗試構建一個表達式樹,其中要過濾的類型僅在運行時已知,並表示為字符串。 在上面的示例中,類型Region已知並直接鍵入:

ParameterExpression pe = Expression.Parameter(typeof(Region), "region");

在我的應用程序中,我已經能夠將其重寫為:

ParameterExpression pe = Expression.Parameter(Type.GetType("mystring"), "listData");

我的絆腳石就是這個例子:

MethodCallExpression whereCallExpression = Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { query.ElementType },
            query.Expression,
            Expression.Lambda<Func<Region, bool>>(e3, new ParameterExpression[] { pe }));
var results = query.Provider.CreateQuery<Region>(whereCallExpression);

在這兩行中, Region是直接鍵入的。 有沒有辦法動態使用字符串“Region”來實現同樣的事情?

當然,但你必須了解其含義。 類型名稱Region是編譯時類型。 有了它,您可以生成強類型查詢。 但是,由於您在編譯時沒有該類型,您仍然可以生成查詢,但不會強類型化。

您可以使用非泛型重載生成未知編譯時類型的lambda表達式。 CreateQuery()方法類似。

以下是同一查詢的兩個版本,用於檢查某些屬性值是否與給定值匹配。 一個是通用的,另一個不是。

通用版本隱式地從查詢類型中獲取類型。

public IQueryable<TSource> PropertyEqualsValue<TSource>(IQueryable<TSource> query,
        string propertyName, object value)
{
    var param = Expression.Parameter(typeof(TSource));
    var body = Expression.Equal(
        Expression.Property(param, propertyName),
        Expression.Constant(value)
    );
    var expr = Expression.Call(
        typeof(Queryable),
        "Where",
        new[] { typeof(TSource) },
        query.Expression,
        Expression.Lambda<Func<TSource, bool>>(body, param)
    );
    return query.Provider.CreateQuery<TSource>(expr);
}
var query = PropertyEqualsValue(SomeTable, "SomeColumn", "SomeValue");

另一種類型取自提供的typeName 請注意,在創建查詢時,我們無法提供類型,因為我們在編譯時不知道類型是什么。

public IQueryable PropertyEqualsValue(IQueryable query,
        Type type, string propertyName, object value)
{
    var param = Expression.Parameter(type);
    var body = Expression.Equal(
        Expression.Property(param, propertyName),
        Expression.Constant(value)
    );
    var expr = Expression.Call(
        typeof(Queryable),
        "Where",
        new[] { type },
        query.Expression,
        Expression.Lambda(body, param)
    );
    return query.Provider.CreateQuery(expr);
}
var type = Type.GetType("Some.Type.Name");
var query = PropertyEqualsValue(SomeTable, type, "SomeColumn", "SomeValue");

暫無
暫無

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

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