我有一个网格视图搜索过滤工具,但有一个回退。在这里,当用户使用集合搜索字符串时,我必须使其像不敏感的包含。
这是我的助手方法:
public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
{
if (colName != null && searchText != null)
{
var parameter = Expression.Parameter(typeof(T), "m");
var propertyExpression = Expression.Property(parameter, colName);
System.Linq.Expressions.ConstantExpression searchExpression = null;
System.Reflection.MethodInfo containsMethod = null;
// this must be of type Expression to accept different type of expressions
// i.e. BinaryExpression, MethodCallExpression, ...
System.Linq.Expressions.Expression body = null;
Expression ex1 = null;
Expression ex2 = null;
Expression converted = null;
switch (colName)
{
case "JobID":
case "status_id":
Int32 _int = Convert.ToInt32(searchText);
searchExpression = Expression.Constant(_int);
containsMethod = typeof(Int32).GetMethod("Equals", new[] { typeof(Int32) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
case "group_id":
Int32? _int1 = Convert.ToInt32(searchText);
searchExpression = Expression.Constant(_int1);
converted = Expression.Convert(searchExpression, typeof(object));
containsMethod = typeof(Int32?).GetMethod("Equals", new[] { typeof(Int32?) });
body = Expression.Call(propertyExpression, containsMethod, converted);
break;
case "FileSize":
case "TotalFileSize":
Int64? _int2 = Convert.ToInt64(searchText);
searchExpression = Expression.Constant(_int2);
converted = Expression.Convert(searchExpression, typeof(object));
containsMethod = typeof(Int64?).GetMethod("Equals", new[] { typeof(Int64?) });
body = Expression.Call(propertyExpression, containsMethod, converted);
break;
// section for DateTime? properties
case "PublishDate":
case "Birth_date":
case "Anniversary_date":
case "Profile_Updated_datetime":
case "CompletedOn":
DateTime currentDate = DateTime.ParseExact(searchText, "dd/MM/yyyy", null);
DateTime nextDate = currentDate.AddDays(1);
ex1 = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(currentDate, typeof(DateTime?)));
ex2 = Expression.LessThan(propertyExpression, Expression.Constant(nextDate, typeof(DateTime?)));
body = Expression.AndAlso(ex1, ex2);
break;
// section for DateTime properties
case "Created_datetime":
case "Reminder_Date":
case "News_date":
case "thought_date":
case "SubscriptionDateTime":
case "Register_datetime":
case "CreatedOn":
DateTime currentDate1 = DateTime.ParseExact(searchText, "dd/MM/yyyy", null);
DateTime nextDate1 = currentDate1.AddDays(1);
ex1 = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(currentDate1));
ex2 = Expression.LessThan(propertyExpression, Expression.Constant(nextDate1));
body = Expression.AndAlso(ex1, ex2);
break;
default:
searchExpression = Expression.Constant(searchText);
containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
}
var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
return queryable.Where(predicate);
}
else
{
return queryable;
}
}
这里默认情况下我必须使containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
不区分大小写。
任何人都可以帮助我......
我发现此查询部分存在问题:
post = db.Posts.Where(p => (p.ToUser_id.Equals(user_id) || p.ToUser_id.Equals(null)) && p.User_id != user_id).OrderByDescending(p => p.Sent_Datetime).Select(p => new
{
Id = p.Id,
Title = p.Title,
Publisher = db.Users.Where(u => u.Id.Equals(p.User_id)).Select(u => u.First_name + ' ' + u.Last_name).FirstOrDefault(),
ToUser = db.Users.Where(u => u.Id.Equals(p.ToUser_id)).Select(u => u.First_name + ' ' + u.Last_name).FirstOrDefault(),
PublishDate = p.Sent_Datetime,
IsFile = p.IsFileAttached,
CategoryName = db.Categories.Where(c => c.Id.Equals(p.Category_id)).Select(c => c.Category_name).FirstOrDefault(),
status_name = db.Status.Where(s => s.Id.Equals(p.status_id)).Select(s => s.status_name).FirstOrDefault(),
Group_name = db.Groups.Where(g => g.Id.Equals(p.group_id)).Select(g => g.Group_name).FirstOrDefault(),
FileSize = p.TotalFileSize
}).FilterForColumn(ColumnName, SearchText).ToList();
The translation of String.IndexOf to SQL does not support versions with a StringComparison argument.
答案 0 :(得分:2)
如果您将默认案例更改为使用IndexOf
而不是Contains
,则应解决您的问题:
default:
propertyExpression = Expression.Property(parameter, colName);
searchExpression = Expression.Constant(searchText);
containsMethod = typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) });
ConstantExpression compareExpression = Expression.Constant(StringComparison.OrdinalIgnoreCase);
ex1 = Expression.Call(propertyExpression, containsMethod, searchExpression, compareExpression);
body = Expression.NotEqual(ex1, Expression.Constant(-1));
break;
答案 1 :(得分:1)
我得到了更准确的答案
当我追加ToLower()函数时。
default:
searchExpression = Expression.Constant(searchText.ToLower());
containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;