我有一个显示表格记录的网格。在这个网格上我使用自定义分页和排序,所以我也需要使用自定义列过滤。
.dll
上面的代码片段在类型var expression = ExpressionBuilder.Expression<EventModel>(request.Filters);
表达式的控制器中从Kendo Grid获取过滤条件,
并将其转换为字符串,并将其传递给DAL代码,如下所示,
System.Linq.Expressions.Expression<Func<EventModel,bool>>
在DAL中,我需要将string filterExpression = ExpressionBuilder.Expression<EventModel>(request.Filters).ToString();
List<EventModel> eventModelList = new List<EventModel>();
eventModelList = eventComponent.GetEventData(request.PageSize, request.Page, searchstring, sortDirection, sortColumnName, filterExpression, ref recCount);
从字符串转换为filterExpression
System.Linq.Expressions.Expression<Func<EventModel,bool>>
收到错误无法从字符串转换为System.Linq.Expressions.Expression&gt;'。
所以有人可以告诉我如何在C#中将字符串转换为var res = eventInfo.AsQueryable().Where(filterExpression);//Gets error here
lstEventInfo = lstEventInfo.AsQueryable().Where(res);
类型。
答案 0 :(得分:1)
这是一个如何动态创建的简单示例。
public class Mock
{
public int Id { get; set; }
public int ForeignId { get; set; }
public decimal Total { get; set; }
}
class Program
{
static void Main(string[] args)
{
var list = new List<Mock>()
{
new Mock{
Id = 1,
ForeignId = 1,
Total = 100,
},
};
var query = list.AsQueryable();
// t
var parameter = Expression.Parameter(typeof(Mock), "t");
// t.Total
var propertyExpression = Expression.PropertyOrField(parameter, "Total");
// 100.00M
var constant = Expression.Constant(100M, typeof(decimal));
// t.Total == 100.00M
var equalExpression = Expression.Equal(propertyExpression, constant);
// t => t.Total == 100.00M
var lambda = Expression.Lambda(equalExpression, parameter);
// calls where.
var whereExpression = Expression.Call(typeof(Queryable), "Where", new[] { query.ElementType }, query.Expression, lambda);
// add where to query.
query = query.Provider.CreateQuery(whereExpression) as IQueryable<Mock>;
Console.ReadKey();
}
}
但你可以使用这个
https://github.com/PoweredSoft/DynamicLinq
这是Nuget包
https://www.nuget.org/packages/PoweredSoft.DynamicLinq/
这里有一个小样本如何进行简单的网页过滤
https://github.com/PoweredSoft/DynamicLinq#how-it-can-be-used-in-a-web-api
您可以调整它以适合您的过滤器表达模型。
[HttpGet][Route("FindClients")]
public IHttpActionResult FindClients(string filterField = null, string filterValue = null,
string sortProperty = "Id", int? page = null, int pageSize = 50)
{
var ctx = new MyDbContext();
var query = ctx.Clients.AsQueryable();
if (!string.IsNullOrEmpty(filterField) && !string.IsNullOrEmpty(filterValue))
query = query.Query(t => t.Contains(filterField, filterValue)).OrderBy(sortProperty);
// count.
var clientCount = query.Count();
int? pages = null;
if (page.HasValue && pageSize > 0)
{
if (clientCount == 0)
pages = 0;
else
pages = clientCount / pageSize + (clientCount % pageSize != 0 ? 1 : 0);
}
if (page.HasValue)
query = query.Skip((page.Value-1) * pageSize).Take(pageSize);
var clients = query.ToList();
return Ok(new
{
total = clientCount,
pages = pages,
data = clients
});
}
另一种方法是使用DynamicLinq
https://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library
答案 1 :(得分:0)
我编写了此代码段,用于从字符串转换为表达式。
public List<Product> Get(string filter = null)
{
var p = Expression.Parameter(typeof(Product), "x");
var e = (Expression)DynamicExpressionParser.ParseLambda(new[] { p }, null, filter);
var typedExpression = (Expression<Func<Product, bool>>)e;
var res = _productDal.GetList(typedExpression);
return res;
}
我将 System.Linq.Dynamic.Core 名称空间用于Asp.Net Core。您可以为Asp.Net使用 System.Linq.Dynamic 命名空间。
如果您使用经典的Asp.Net而不是Asp.Net Core,则应编写
var e = (Expression)DynamicExpression.ParseLambda(new[] { p }, null, filter);
代替
var e = (Expression)DynamicExpressionParser.ParseLambda(new[] { p }, null, filter);
您的字符串参数(命名为 过滤器 )应该类似于“(x.ProductID> 10)” >
如果您的字符串参数不同,则可以使用以下代码段将表达式从字符串转换为字符串,以将相同的字符串参数转换为 Get 方法。
public static string Select(this Grid _grid, Expression<Func<Product, bool>> filter = null)
{
//filter = {x => (x.ProductID > 1)}
BinaryExpression be = filter.Body as BinaryExpression;
//be = {(x.ProductID > 1)}
return be.ToString();
}