【发布时间】:2017-04-18 12:10:13
【问题描述】:
目前,我有一个有效的辅助函数,它创建一个简单的表达式来搜索通用实体 (TEntity) 中的搜索词(单个单词/短语)。它创建以下表达式:
q => q.Product.ProductTitle.Contains( searchText: 'red shirt' )
我只需要扩展这个助手来搜索搜索词中包含的每个单词(例如 searchText:'red shirt' --> searchTerms:['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<PropertyInfo> searchPropertiesList, SearchType searchType, params string[] args),然后您只需要处理传入的 1 个(或更多)args。请参阅:msdn.microsoft.com/en-us/library/w5zay9db.aspx -
感谢您的反馈扎克。我会考虑在未来更新或改变行为。
标签: c# linq generics lambda expression