3

次のようなコードがたくさん見られます

var customrs = MyDataContext.Customers.Where(...);
if (!String.IsNullOrEmpty(input)) {
  customers = customers.Where(c => c.Email.Contains(input));
}

IQueryable で Where を呼び出す前に、入力が有効であることを確認する拡張メソッドにこれを入れて、次のように呼び出すことができるようにしたいと思います。

customers = MyDataContext.Customers.Where(...)
  .ContainsText(c => c.Email, input);

私の拡張メソッドは次のようになります

public static IQueryable<T> ContainsText<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string text) {
  if (String.IsNullOrEmpty(text) {
    return source;
  }
  else {
    //do something here
  }
}

解析された式で Contains() を呼び出すにはどうすればよいですか? または、解析された式に解析されたテキストが含まれている結果の IQueryable を返す別の方法はありますか?

更新:LinqからSql用です

4

4 に答える 4

3

IQueryableではなく、Stringで拡張を行うと思います。

public static bool ContainsIfNotEmpty( this string source, string text )
{
    if (string.IsNullOrEmpty(text))
    {
       return true; // select all elements
    }
    if (string.IsNullOrEmpty(source))
    {
       return false; // select no elements
    }
    return source.Contains(text); // select only matching
}

次に、次のように使用します。

customers = MyDataContext.Customers
                         .Where( c => c.Email.ContainsIfNotEmpty( input ) );

これにはオブジェクトへの LINQ が必要であることに注意してください。LINQ to SQL で使用する必要がある場合は、ビルダー メソッドを使用して式を作成することをお勧めします。現在VSにアクセスできないため、以下はテストされていないことに注意してください。同様の例については、 Andrew Peters のブログ エントリや、Expressionクラスに関するドキュメントを参照してください。

public static class ExpressionBuilders
{
    public static Expression<Func<T,bool>> ContainsBuilder<T>( string column, string text )
    {
          ParameterExpression parameter = new Expression.Parameter( typeof(T), "t" );

          if (string.IsNullOrEmpty(text))
          {
              return (Expression<Func<T,bool>>)QueryExpression.Lambda( Expression.Constant( true ), parameter );
          }

          MethodInfo contains = typeof(T).GetMethod("Contains");
          Expression textExpression = Expression.Constant(text);
          Expression containsExpression = Expression.Call(parameter,contains,textExpression);

          return (Expression(Func<T,bool>))QueryExpression.Lambda( containsExpression, parameter );
    }
}

使用されます:

var predicate = ExpressionBuilders.ContainsBuilder<Customer>( "Email", input );

customers = MyDataContext.Customers.Where( predicate );
于 2009-11-06T15:06:15.550 に答える
1

を使用すると、次のことが可能になりますIEnumerable<T>

public static IEnumerable<T> ContainsText<T>(
    this IEnumerable<T> source, Func<T, string> selector, string text)
{
  return source.Where(
      x => (!string.IsNullOrEmpty(selector(x)) &&
           (selector(x).Contains(text))));
}

唯一のオプションにとどまるには、IQueryable<T>tvanfosson が提案した Dynamic Linq またはUser Defined Functionsのいずれかになります。

しかし、正直なところ、あなたはそのままでいるかもしれませんWhere

于 2009-11-06T15:07:24.023 に答える
0

代わりにこれを行うことができると思います:

customers = MyDataContext.Customers.Where(c =>  (string.IsNullOrEmpty(input) || c.Email.Contains(input)));
于 2009-11-06T14:51:12.373 に答える