Linq to entities包含动态字段和int32

时间:2013-07-18 21:34:51

标签: c# linq-to-entities dynamic-programming

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

  1. 使用.Contains方法在我的SQL Server上执行“LIKE”操作
  2. 将Int32中的值转换为字符串,以便我可以在其上执行.Contains
  3. 允许用户传入自定义字段名称,因此使用类似SqlFunctions.StringConvert((double)d.ID).Contains(idSearch)将无效。我不知道我要检查什么专栏。
  4. 最好,我想做这样的事情:

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

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

1 个答案:

答案 0 :(得分: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);