0
現在、私は、検索用語(単一単語/フレーズ)を一般的なエンティティ(TEntity)で検索する単純な式を作成する作業ヘルパ関数を持っています。 >のSearchTerms - 「赤シャツ」:[「赤」、「Tシャツ」これは、次の式を作成:Where(またはAny)とジェネリックスを使用する検索リストの動的式ツリー
q => q.Product.ProductTitle.Contains(searchText: 'red shirt')
を私は単純に検索用語(たとえば、検索テキストに含まれる各単語を検索するには、このヘルパーを拡張する必要があります])
var searchTerms = searchText.ToLower().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
searchTerms.Any(s => !q.Product.ProductTitle.ToLower().Contains(s))
この機能は以下のとおりです。コードを完成させる必要があります。
public static Expression<Func<TEntity, bool>> CreateSearchQuery(List<PropertyInfo> searchPropertiesList, string searchText, SearchType searchType = SearchType.Contains)
{
if(string.IsNullOrWhiteSpace(searchText) || searchPropertiesList == null || searchPropertiesList.Count <= 0)
{
return null;
}
var searchTerms = searchText.ToLower().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
var searchExpressionList = new List<Expression<Func<TEntity, bool>>>();
foreach(var property in searchPropertiesList.Where(x => x.GetCustomAttributes(false).Any(c => c.GetType() != typeof(NotMappedAttribute))))
{
//search param
var searchParam = Expression.Parameter(typeof(string), "s");
//search type
var searchTypeMethod = typeof(string).GetMethod(searchType.ToString(), new[] { typeof(string) });
//entity expression.
var entityParam = Expression.Parameter(typeof(TEntity), "q");
var entityProperty = Expression.Property(entityParam, property);
var entityExpression = Expression.Call(
Expression.Call(entityProperty, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes)),
searchTypeMethod,
Expression.Call(searchParam, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes))
);
var entityPredicateBody = Expression.Lambda<Func<TEntity, bool>>(entityExpression, entityParam);
////TODO: CONSIDER EACH TERM AND CREATE WHERE/ANY EXPRESSION
//searchTerms.Any(s => !q.Product.ProductTitle.ToLower().Contains(s))
//var filterExpression = Expression.Call(
// typeof(Enumerable),
// "Where",
// new[] { typeof(TEntity) },
// searchParam,
// entityPredicateBody);
//var expressionBody = Expression.Lambda<Func<TEntity, bool>>(filterExpression, searchParam);
//TODO: REPLACE WITH NEW EXPRESSION (expressionBody)
searchExpressionList.Add(entityPredicateBody);
}
文字列を一重引用符で囲むのはなぜですか( '' red shirt'')?複数の文字列を受け入れるように拡張したい場合、これを関数argsとして使うことができます: '(List searchPropertiesList、SearchType searchType、params string [] args)'なら、 1(またはそれ以上)の 'args'が渡されます。https://msdn.microsoft.com/en-us/library/w5zay9db.aspx –
ご意見ありがとうございます。私は今後の行動の更新や変更を見ていきます。 –