繁体   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