0

我很难弄清楚如何在一个电话中完成以下所有三个操作:

  1. 使用 .Contains 方法在我的 SQL Server 上执行“LIKE”操作
  2. 将值从 Int32 转换为字符串,以便我可以对其执行 .Contains
  3. 允许用户传入自定义字段名称,因此使用 SqlFunctions.StringConvert((double)d.ID).Contains(idSearch) 之类的名称将不起作用。我不知道我要检查哪一栏。

最好,我想做这样的事情:

public static class LinqExtensions
{
    public static IQueryable<T> Like<T>(this IQueryable<T> source, string fieldName, object value)
    {
        ... Code here
    }
}

我想我需要使用表达式树来处理这个问题,但是我很难找到任何关于如何使用动态 Linq/表达式树的教程。任何可以帮助我的想法或链接将不胜感激。或者,如果有人有一个已经这样做的图书馆,那就更好了!

4

1 回答 1

0

这是我编写的在 Int32 上执行 LIKE 的扩展方法:

public static class LinqExtensions
{
  public static IQueryable<T> Like<T>(this IQueryable<T> source, string propertyName, object value)
  {
      IQueryable<T> returnQuery = null;
      switch (value.GetType().ToString())
      {
          case "System.String":
              returnQuery = source.Where(LikeLambdaString<T>(propertyName, value.ToString()));
              break;
          default:
              returnQuery = source.Where(LikeLambdaDouble<T>(propertyName, Convert.ToDouble(value)));
              break;        
      }

      return returnQuery;
  }

  public static Expression<Func<T, bool>> LikeLambdaString<T>(string propertyName, string value)
  {
      var linqParam = Expression.Parameter(typeof(T), propertyName);
      var linqProp = GetProperty<T>(linqParam, propertyName);

      var containsFunc = Expression.Call(linqProp,
          typeof(string).GetMethod("Contains"),
          new Expression[] { Expression.Constant(value) });

      return Expression.Lambda<Func<T, bool>>(containsFunc,
              new ParameterExpression[] { linqParam });
  }

  public static Expression<Func<T, bool>> LikeLambdaDouble<T>(string propertyName, double? value)
  {
      string stringValue = (value == null) ? string.Empty : value.ToString();
      var linqParam = Expression.Parameter(typeof(T), propertyName);
      var linqProp = GetProperty<T>(linqParam, propertyName);

      var stringConvertMethodInfo =
          typeof(SqlFunctions).GetMethod("StringConvert", new Type[] { typeof(double?) });

      var stringContainsMethodInfo =
          typeof(String).GetMethod("Contains");

      return Expression.Lambda<Func<T, bool>>(
          Expression.Call(Expression.Call(
                  stringConvertMethodInfo,
                  Expression.Convert(
                      linqProp,
                      typeof(double?))),
              stringContainsMethodInfo,
              Expression.Constant(stringValue)),
          linqParam);
  }

  public static MemberExpression GetProperty<T>(ParameterExpression linqParam, string propertyName)
  {
      List<string> propertyNames = propertyName.Split('.').ToList();

      var linqProp = Expression.Property(linqParam, propertyNames[0]);

      for (int i = 1; i < propertyNames.Count(); i++)
      {
          linqProp = Expression.Property(linqProp, propertyNames[i]);
      }

      return linqProp;
  }

}

你会这样称呼它:

returnQuery = returnQuery.Like("ID", doubleValue);
于 2013-08-08T14:19:43.137 回答