Sha*_*hal 0 c# linq asp.net linq-expressions
我为过滤器列构建了一种辅助方法。
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我将这段代码传递给 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我想要过滤的查询:
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();
Run Code Online (Sandbox Code Playgroud)
这是我的表格架构:
+--------------------------+---------------+
| 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 |
+--------------------------+---------------+
Run Code Online (Sandbox Code Playgroud)
然而在 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
Run Code Online (Sandbox Code Playgroud)
我没有对你投反对票,但我认为你投了反对票,因为你给了我们太多的信息需要挖掘,而且你的行太长,需要大量的水平滚动。您应该将其削减到可以重现问题的最小代码集。
看起来您正在FilterForColumn使用列名“party_id”进行调用,但这紧接在 a 后面,Select()该 a 生成IQueryable具有名为 属性的匿名类型
换句话说,没有名为 的属性party_id。事实上,case语句中的大多数列名似乎都不存在于该匿名类型中。
我不确定我能否准确地告诉您如何解决此问题,但简单的答案可能是在您正在构造的匿名类型中包含所有所需的列值。
| 归档时间: |
|
| 查看次数: |
5777 次 |
| 最近记录: |