0

1 回の呼び出しで次の 3 つすべてを行う方法を理解するのに苦労しています。

  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 に答える