如何将字符串转换为System.Linq.Expressions.Expression

时间:2018-03-21 23:07:07

标签: c#

我有一个显示表格记录的网格。在这个网格上我使用自定义分页和排序,所以我也需要使用自定义列过滤。

.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

Converting to Expression type

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); 类型。

2 个答案:

答案 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();
    }