编程语言
首页 > 编程语言> > c#-动态构建表达式树

c#-动态构建表达式树

作者:互联网

我正在追踪这个出色的例子:Convert Linq to Sql Expression to Expression Tree

在我的情况下,我试图构建一个表达式树,其中要过滤的类型仅在运行时才知道,并表示为字符串.在上面的示例中,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");

标签:linq,c,expression-trees
来源: https://codeday.me/bug/20191026/1939801.html