我为过滤网格视图记录过滤器构建了一个谓词:
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;
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));
var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
return queryable.Where(predicate);
}
}
这不适用于此查询:
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.
这个错误说我不理解......
根据评论建议我修改我的代码:
default:
searchExpression = Expression.Constant(searchText);
containsMethod = typeof(string).GetMethod("SqlMethods.Like", new[] { typeof(string) });
body = Expression.Call(propertyExpression, containsMethod, searchExpression);
break;
但现在它给我的错误如下:
Value cannot be null.
Parameter name: method
我发现了一个新的错误:
Server Error in '/CRM' Application.
Static method requires null instance, non-static method requires non-null instance.
Parameter name: instance
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: Static method requires null instance, non-static method requires non-null instance.
Parameter name: instance
Source Error:
Line 75: searchExpression = Expression.Constant(searchText);
Line 76: containsMethod = typeof(System.Data.Linq.SqlClient.SqlMethods).GetMethod("Like", new[] { typeof(string), typeof(string) });
Line 77: body = Expression.Call(propertyExpression, containsMethod, searchExpression);
Line 78: break;
Line 79: }
Source File: f:\CRM\App_Code\Helper.cs Line: 77
Stack Trace:
[ArgumentException: Static method requires null instance, non-static method requires non-null instance.
Parameter name: instance]
System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method) +4189320
System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments) +55
System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments) +29
Helper.FilterForColumn(IQueryable`1 queryable, String colName, String searchText) in f:\CRM\App_Code\Helper.cs:77
Staff_Raise_Ticket.FillGrid(String StartAlpha, Int32 GroupByENTYPE, String ColumnName, String SearchText) in f:\CRM\Staff\Raise_Ticket.aspx.cs:625
Staff_Raise_Ticket.btnsearch_Click(Object sender, EventArgs e) in f:\CRM\Staff\Raise_Ticket.aspx.cs:1918
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +176
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1