IQueryableの汎用検索拡張メソッドを作成しました。これにより、単一のプロパティを検索して、検索語がその中に含まれているかどうかを確認できます。
http://jnye.co/Posts/6/c%23-generic-search-extension-method-for-iqueryable
ここで、ユーザーが複数のプロパティを選択してそれぞれのプロパティ内を検索できるようにし、プロパティにテキストが含まれている場合は一致させたいと思います。
コード:
ユーザーは、この検索を実行するために次のコードを入力します。
string searchTerm = "Essex";
context.Clubs.Search(searchTerm, club => club.Name, club => club.County)
//Note: If possible I would rather something closer to the following syntax...
context.Clubs.Search(club => new[]{ club.Name, club.County}, searchTerm);
// ... or, even better, something similar to this...
context.Clubs.Search(club => new { club.Name, club.County}, searchTerm);
これにより、名前または郡に「エセックス」が含まれるゴルフクラブが返されます。
public static IQueryable<TSource> Search<TSource>(this IQueryable<TSource> source, string searchTerm, params Expression<Func<TSource, string>>[] stringProperties)
{
if (String.IsNullOrEmpty(searchTerm))
{
return source;
}
// The lamda I would like to reproduce:
// source.Where(x => x.[property1].Contains(searchTerm)
// || x.[property2].Contains(searchTerm)
// || x.[property3].Contains(searchTerm)...)
//Create expression to represent x.[property1].Contains(searchTerm)
var searchTermExpression = Expression.Constant(searchTerm);
//Build parameters
var parameters = stringProperties.SelectMany(prop => prop.Parameters);
Expression orExpression = null;
//Build a contains expression for each property
foreach (var stringProperty in stringProperties)
{
var checkContainsExpression = Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);
if (orExpression == null)
{
orExpression = checkContainsExpression;
}
//Build or expression for each property
orExpression = Expression.OrElse(orExpression, checkContainsExpression);
}
var methodCallExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { source.ElementType },
source.Expression,
Expression.Lambda<Func<TSource, bool>>(orExpression, parameters));
return source.Provider.CreateQuery<TSource>(methodCallExpression);
}
エラー
提供されるパラメーターの数を1に変更した場合:
Expression.Lambda<Func<TSource, bool>>(orExpression, parameters.First()));
新しいエラーが発生します:
アップデート