如何动态使用SqlFunctions.PatIndex

时间:2013-07-05 17:50:08

标签: c# linq entity-framework

我需要在表达式中使用SqlFunctions.PatIndex。

Func<IQueryable<T>, KendoFilterDescription, IQueryable<T>> appendFilter =
                (filteredData, filter) => filteredData.Where(String.Format("System.Data.Objects.SqlClient.SqlFunctions.PatIndex(\"@0\", {0})", filter.Field), ParsePropertyValue(filter));

但我得到一个例外:No property or field 'System' exists in type 'RecordListItem'

如何使用此功能?

1 个答案:

答案 0 :(得分:2)

由于代码示例中的长表达式可能很难看到,但似乎“Where”子句包含错误,因为它不是可以缩减为Func<T, bool>的表达式。

我假设这是您收到编译器错误的原因。如果没有关于KendoFilterDescription是什么,ParsePropertyValue做什么以及您尝试使用PatIndex过滤什么的更多信息,很难为您找到一个好的答案。

所以现在我会尝试猜测:

  1. 您正尝试使用PatIndex表达式过滤IQueryable。
  2. 如果评估的PatIndex表达式未返回0,则“Where”应评估为true,因此记录包含在结果中。
  3. 您希望PatIndex表达式的stringPattern参数等于ParsePropertyValue(filter)的返回值,即要匹配的模式。
  4. 您希望PatIndex表达式的target参数等于T的名称为filter.Field的属性或字段的值。
  5. 举个例子,让我们取一个Person(T)类,其属性为FirstName和LastName。假设您希望过滤包含某个短语的FirstName,那么您可能希望构建一个表达式:

    Func<string, string> BuildContainsPattern = phrase => string.Format("%{0}%", phrase);
    Func<IQueryable<Person>, string, IQueryable<Person>> whereFirstNameContains =
                (data, phrase) => data.Where(p => SqlFunctions.PatIndex(BuildContainsPattern(phrase), p.FirstName) > 0);
    

    假设这(基本上)是正确的。我们需要一些构建块,这些构建块一起允许我们构建一个Expression<Func<T, bool>>,可以传递给Where的{​​{1}}子句。

    好的,首先是困难的部分。下面的IQueryable<T>函数可以为我们构建这个表达式,只要我们为它提供(1)BuildFilterExpression作为stringPattern函数的第一个参数和(2)实体类型PatIndex上的属性名称,我们希望将其用作T函数的第二个参数。

    因此,如果我对PatIndexParsePropertyValue(filter)表示的假设是正确的,则下面的代码应使用过滤器提供的设置进行过滤。

    filter.Field

    显然,我可能完全猜错了,但我想你会改进你想要达到的目标的描述。