gpt4 book ai didi

c# - 如何动态使用 SqlFunctions.PatIndex

转载 作者:太空宇宙 更新时间:2023-11-03 11:01:38 24 4
gpt4 key购买 nike

我需要在表达式中使用 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));

但我得到一个异常:'RecordListItem' 类型中不存在属性或字段'System'

如何使用这个功能?

最佳答案

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

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

所以现在我会尝试一个疯狂的猜测:

  1. 您正在尝试使用 PatIndex 表达式过滤 IQueryable。
  2. 如果计算的 PatIndex 表达式不返回 0,则“Where”的计算结果应为真,因此记录包含在结果中。
  3. 你想要 stringPattern PatIndex 表达式的参数等于 ParsePropertyValue(filter) 的返回值,即要匹配的模式。
  4. 你想要 target PatIndex 表达式的参数等于 T 的属性或字段的值用名字filter.Field .

作为示例,让我们以具有属性 FirstName 和 LastName 的类 Person (T) 为例。假设您希望过滤包含特定短语的 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);

假设这是(基本上)正确的。我们需要一些构建 block ,它们一起允许我们构建一个 Expression<Func<T, bool>>可以传递给 Where IQueryable<T> 的条款.

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

所以如果我的假设是什么ParsePropertyValue(filter)filter.Field代表是正确的,下面的代码应该使用过滤器提供的设置进行过滤。

using System;
using System.Linq;
using System.Reflection;
using System.Data.Objects.SqlClient;
using System.Linq.Expressions;

public class FilterDescription
{
public enum FilterPatternType
{
Contains = 1,
Range = 2, // [^0-9]
}
public string Field { get; set; }
public string FilterPhrase { get; set; }
public FilterPatternType PatternType { get; set; }
}

public static class FilterBuilder
{
private static readonly MethodInfo PatIndexMethod = typeof(SqlFunctions).GetMethod("PatIndex");
private static readonly ConstantExpression ValueZero = Expression.Constant(0, typeof(int?));

public static string ParsePropertyValue(FilterDescription filter)
{
switch (filter.PatternType)
{
case FilterDescription.FilterPatternType.Contains:
return string.Format("%{0}%", filter.FilterPhrase);
case FilterDescription.FilterPatternType.Range:
return string.Format("[^{0}]", filter.FilterPhrase);
default:
throw new InvalidOperationException("Pattern type not supported");
}
}

public static Expression<Func<TEntity, bool>> BuildFilterExpression<TEntity>(string patternString, string targetProperty)
{
var patternStringArg = Expression.Constant(patternString);
var entityType = Expression.Parameter(typeof(TEntity), "item");
var targetPropertyArg = Expression.PropertyOrField(entityType, targetProperty);

MethodCallExpression patIndexCall = Expression.Call(PatIndexMethod, patternStringArg, targetPropertyArg);

var isGreaterThanZero = Expression.GreaterThan(patIndexCall, ValueZero);

return Expression.Lambda<Func<TEntity, bool>>(isGreaterThanZero, entityType);
}

public static Expression<Func<TEntity, bool>> BuildFilterExpression<TEntity>(FilterDescription filter)
{
var pattern = ParsePropertyValue(filter);
return BuildFilterExpression<TEntity>(pattern, filter.Field);
}

public static IQueryable<TEntity> Filter<TEntity>(this IQueryable<TEntity> toFilter, FilterDescription filter)
{
return toFilter.Where(BuildFilterExpression<TEntity>(filter));
}
}

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}

class Program
{
private static IQueryable<Person> GetPersons()
{
return (IQueryable<Person>)null; // use your own data.
}

public static void Main(params string[] args)
{
var filter = new FilterDescription()
{
PatternType = FilterDescription.FilterPatternType.Contains,
Field = "FirstName",
FilterPhrase = "ed"
};
var filtered = GetPersons().Filter(filter);
}
}

很明显,我的疯狂猜测可能完全错了,但我想您会改进对您要实现的目标的描述。

关于c# - 如何动态使用 SqlFunctions.PatIndex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17494442/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com