您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 4浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

解答网友提问:如何构建动态表达式实现高级查询服务

寒冰屋 发布时间:2021-07-13 11:49:43 ,浏览量:4

上次我们介绍了"一秒创建高级查询服务"。前天,有网友在公众号后台问我,怎么使用动态表达式:

图片

我想应该是客户提出了更高的要求,查询的条件不仅限于大于、小于,更加多样化,需要动态组合成条件,类似下图: 

图片

那么,有不有什么方式能快速实现这一业务要求呢?!

思考

我们使用IQueryable去查询数据,那么只需要传入的参数能够转成Lambda表达式就可以了。

当然,可以使用Expression.Lambda方法去动态创建表达式树,但是那样对传入的数据模型格式有一定要求。

能不能就用字符串生成动态表达式呢?

实现方式

Roslyn是微软开源的.NET编译器,但是鲜为人知的,它还提供了CSharp scripting API。

创建Asp.Net Core Web API项目,引用Nuget包Microsoft.CodeAnalysis.CSharp.Scripting

然后,修改WeatherForecastController.cs的Get方法,假定查询条件是从前端拼接后传递过来的:

[HttpGet]
public async Task Get()
{
    //温度大于20, Summary必须以C开头
    var filter = @"p => p.TemperatureC > 20 && p.Summary.StartsWith(""C"")";

    //由于使用了String.StartsWith,所以要引用String所在的Assembly
    var options = ScriptOptions.Default.AddReferences(typeof(WeatherForecast).Assembly,
        typeof(String).Assembly);

    Func expression = await CSharpScript.EvaluateAsync(filter, options);

    var rng = new Random();
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
    }).AsQueryable().Where(expression)
    .ToArray();
}

运行程序,可以看到只返回满足条件的数据(默认应该是5条),如下图: 

图片

结论

需要注意的是,动态编译肯定是有一定的性能损失的,这就要看业务上如何取舍了。

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.1034s