我为过滤器列构建了一个辅助方法。
public static class Helper
{
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 "party_id":
case "type_id":
case "status_id":
case "category_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 "country_id":
case "state_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;
// 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_date":
case "Register_Date":
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;
}
}
}
现在这个代码我将值传递给FilterColumn:
protected void btnsearch_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
using(DataClassesDataContext db = new DataClassesDataContext())
{
System.Threading.Thread.Sleep(2000);
if (DDL_Column_List.SelectedItem.Value != "-1" && txtsearch.Text.Trim() != "")
{
switch (DDL_Column_List.SelectedItem.Text.ToString())
{
case "Ticket ID":
Session["ColumnName"] = "Ref_no";
Session["SearchText"] = txtsearch.Text.Trim();
break;
case "Name":
Session["ColumnName"] = "party_id";
Session["SearchText"] = db.Parties.Where(p => p.Name.Contains(txtsearch.Text.Trim())).Select(p => p.Id).FirstOrDefault().ToString();
break;
case "Status":
Session["ColumnName"] = "status_id";
Session["SearchText"] = db.Status.Where(s => s.StatusName.Contains(txtsearch.Text.Trim())).Select(s => s.Id).FirstOrDefault().ToString();
break;
case "Category":
Session["ColumnName"] = "category_id";
Session["SearchText"] = db.Categories.Where(c => c.category_name.Contains(txtsearch.Text.Trim())).Select(c=>c.Id).FirstOrDefault().ToString();
break;
case "Date Created":
Session["ColumnName"] = "Created_date";
Session["SearchText"] = txtsearch.Text.Trim();
break;
}
}
else
{
Session["SearchText"] = null;
Session["ColumnName"] = null;
}
this.FillGrid((String)Session["StartAlpha"] ?? null, (String)Session["GroupByENTYPE"] ?? null, (List<int?>)Session["GroupByCategory"] ?? null, (List<int?>)Session["GroupByStatus"] ?? null, (String)Session["ColumnName"] ?? null, (String)Session["SearchText"] ?? null);
UpdatePanel5.Update();
}
}
}
这是我想要过滤的查询:
var enquiry = db.EnquiryHistories.Where(i => i.enttype_id.Equals(entrytypeid) && GroupByCategory.Contains(i.category_id) && GroupByStatus.Contains(i.status_id) && (i.ForwardTo.Equals(userid) || i.AttendBy.Equals(userid))).OrderByDescending(i => i.Activity_start_datetime).Select(i => new
{
Ref_no = i.Ref_no,
Name = db.Parties.Where(p => p.Id.Equals(i.party_id)).Select(p => p.Name).SingleOrDefault(),
StatusName = db.Status.Where(s => s.Id.Equals(i.status_id)).Select(s => s.StatusName).SingleOrDefault(),
CategoryName = db.Categories.Where(c => c.Id.Equals(i.category_id)).Select(c => c.category_name).SingleOrDefault(),
IsUregent = i.IsUregent,
Created_date = i.Activity_start_datetime
}).FilterForColumn(ColumnName, SearchText).ToList();
这是我的表格架构:
+--------------------------+---------------+
| Column Name | Data Type |
+--------------------------+---------------+
| Ref_no | char(14) |
| party_id | int |
| category_id | int |
| callFor | text |
| callBy | text |
| AttendBy | char(14) |
| status_id | int |
| status | text |
| ForwardTo | char(14) |
| ForwardFor | int |
| ReplyDate | datetime |
| Remark | text |
| enttype_id | int |
| paystatus_id | int |
| paydate | datetime |
| payperson | varchar(50) |
| paymathod | varchar(50) |
| chqno | varchar(50) |
| bankname | varchar(100) |
| paymentamount | int |
| IsUregent | bit |
| IsRead | bit |
| IsReplied | bit |
| IsDisplay | bit |
| Activity_start_datetime | smalldatetime |
| Activity_expire_datetime | smalldatetime |
+--------------------------+---------------+
如果在party_id的情况下我发现了这个错误:
Server Error in '/CRM' Application.
Instance property 'party_id' is not defined for type '<>f__AnonymousType2`6[System.String,System.String,System.String,System.String,System.Boolean,System.DateTime]'
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: Instance property 'party_id' is not defined for type '<>f__AnonymousType2`6[System.String,System.String,System.String,System.String,System.Boolean,System.DateTime]'
Source Error:
Line 23: {
Line 24: var parameter = Expression.Parameter(typeof(T), "m");
Line 25: var propertyExpression = Expression.Property(parameter, colName);
Line 26: System.Linq.Expressions.ConstantExpression searchExpression = null;
Line 27: System.Reflection.MethodInfo containsMethod = null;
Source File: f:\CRM\App_Code\Helper.cs Line: 25
Stack Trace:
[ArgumentException: Instance property 'party_id' is not defined for type '<>f__AnonymousType2`6[System.String,System.String,System.String,System.String,System.Boolean,System.DateTime]']
System.Linq.Expressions.Expression.Property(Expression expression, String propertyName) +4189559
Helper.FilterForColumn(IQueryable`1 queryable, String colName, String searchText) in f:\CRM\App_Code\Helper.cs:25
Staff_Ticket_History.FillGrid(String StartAlpha, String GroupByENTYPE, List`1 GroupByCategory, List`1 GroupByStatus, String ColumnName, String SearchText) in f:\CRM\Staff\Ticket_History.aspx.cs:347
Staff_Ticket_History.btnsearch_Click(Object sender, EventArgs e) in f:\CRM\Staff\Ticket_History.aspx.cs:597
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
答案 0 :(得分:3)
我没有向你投票,但我认为你有一个downvote,因为你给了我们太多的信息来挖掘你的线太长,需要大量的水平滚动。您应该将其削减到可以重现问题的最小代码集。
看起来您正在使用列名#&#34; party_id&#34;来调用FilterForColumn
,但这是在产生Select()
匿名的IQueryable
之后立即使用名为
换句话说,没有名为party_id
的属性。实际上,看起来case
语句中的大多数列名都不存在于此匿名类型中。
我不确定我是否可以确切地告诉您如何解决此问题,但简单的答案可能是在您构建的匿名类型中包含所有必需的列值。