【问题标题】:How do I build an expression to apply a Where clause generically to an IQueryable<T>?如何构建表达式以将 Where 子句一般应用于 IQueryable<T>?
【发布时间】:2017-04-11 13:49:53
【问题描述】:

我有一个名为 TestObject 的类,带有 Name 参数。

我创建一个列表并添加其中 2 个。我想为任何IQueryable&lt;T&gt; 创建一个通用的Where() 子句方法。

我一直在玩 Expressions,但我真的不知道自己在做什么。

我用一些硬编码值创建了这个方法用于测试,我希望它能够做到collection.Where(c =&gt; c.Name == "Boris")

public static IQueryable<T> Apply<T>(IQueryable<T> collection)
{
    var parameterName = "Name";
    var searchValue = "Boris";

    var selectorParameter = Expression.Parameter(typeof(T), parameterName);
    var searchTermExpression = Expression.Constant(searchValue);    
    var checkEqualsExpression = Expression.Call(selectorParameter, typeof(string).GetMethod("Equals"), searchTermExpression);

var methodCallExpression = Expression.Call(typeof(Queryable),
    "Where",
    new Type[] { collection.ElementType },
    collection.Expression,
    Expression.Lambda<Func<T, bool>>(checkEqualsExpression , ?????));

    return collection.Provider.CreateQuery<T>(methodCallExpression);
}

我不确定????? 中的内容,或者即使这是正确的。谁能给点建议?

【问题讨论】:

  • 您确定Expression.Parameter(typeof(T), parameterName) 参数名称的类型是T。这是T 的属性(我猜这是一个字符串)。你可能需要Expression.Property() 来做这个
  • 我不知道,我从另一个网站复制并粘贴了它,该网站做了与我想要的类似的事情,我正在努力让它工作,但我真的不知道我在做什么.

标签: c# generics expression-trees


【解决方案1】:

这是一个如何做的例子,使用 cmets,它应该澄清你做错了什么。

public static IQueryable<T> Apply<T>(IQueryable<T> collection) {
    var propertyName = "Name";
    var searchValue = "Boris";
    // we have parameter "c"
    var selectorParameter = Expression.Parameter(typeof(T), "c");
    // constant "Boris"
    var searchTermExpression = Expression.Constant(searchValue);
    // "c.Name"
    var selector = Expression.PropertyOrField(selectorParameter, propertyName);
    // "c.Name == "Boris"
    var equal = Expression.Equal(selector, searchTermExpression);
    // c => c.Name == "Boris"
    var where = Expression.Lambda<Func<T, bool>>(equal, selectorParameter);
    return collection.Where(where);
}

【讨论】:

  • 谢谢,这比我想做的要简单得多!我真的很感激。
  • @NibblyPig 如果您还有其他问题,请不要忘记标记为答案,否则人们会一次又一次地提出这个问题并浪费时间认为它仍然没有答案。
  • @Evk 我知道,我想先对其进行测试 :) 它工作得很好,我能够扩展它来做很多其他很酷的东西。非常感谢,我真的很感激。
猜你喜欢
  • 1970-01-01
  • 2020-01-11
  • 2023-03-29
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多