使用outerIt生成动态Linq查询 [英] Generate Dynamic Linq query using outerIt

查看:61
本文介绍了使用outerIt生成动态Linq查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Microsoft的Dynamic Linq(System.Linq.Dynamic)库在运行时生成一些查询.这对我来说非常有效,但是对于一种特定情况而言.

I am using Microsoft's Dynamic Linq (System.Linq.Dynamic) library to generate some queries at run time. This has worked great for me, but for one specific scenario.

简化的情况-我正在尝试查询所有具有用户选择的特定标签且其余额大于某个数字的索赔.

Simplified scenario - I am trying to query all claims which have some specific tags that the user has selected and whose Balance is greater than some number.

static void Main(string[] args)
    {
        var claims = new List<Claim>();
        claims.Add(new Claim { Balance = 100, Tags = new List<string> { "Blah", "Blah Blah" } });
        claims.Add(new Claim { Balance = 500, Tags = new List<string> { "Dummy Tag", "Dummy tag 1" } });

        // tags to be searched for
        var tags = new List<string> { "New", "Blah" };
        var parameters = new List<object>();
        parameters.Add(tags);

        var query = claims.AsQueryable().Where("Tags.Any(@0.Contains(outerIt)) AND Balance > 100", parameters.ToArray());
    }

public class Claim
{
    public decimal? Balance { get; set; }
    public List<string> Tags { get; set; }
}

此查询引发错误:

System.Linq.Dynamic.dll中发生了类型为'System.Linq.Dynamic.ParseException'的未处理的异常 附加信息:类型字符串"中不存在属性或字段余额"

An unhandled exception of type 'System.Linq.Dynamic.ParseException' occurred in System.Linq.Dynamic.dll Additional information: No property or field 'Balance' exists in type 'String'

动态linq解析器似乎试图在Tag而不是Claim对象上找到Balance属性.

Dynamic linq parser seems to try to find the Balance property on the Tag and not on the Claim object.

  • 我尝试在Dynamic Linq中使用 outerIt,innerIt,It 关键字,但似乎都无效.
  • 更改顺序是可行的,但这对我来说不是一个选择,因为在实际应用中,过滤器,运算符和模式将是动态的(由最终用户配置).
  • 将条件放在方括号()中也无济于事.
  • 解决方法-为所选的每个标签创建一个简单的包含条件,例如Tags.Contains("New")或Tags.Contains("Blah")等.但是在实际的应用程序中,它会导致针对每种条件的查询非常复杂/错误,从而导致性能下降.
  • I have tried to play around with outerIt, innerIt, It keywords in Dynamic Linq but none of it seems to work.
  • Changing the sequence works, but that's not an option for me, since in the real application the filters, operators and patterns will be dynamic (configured by end user).
  • Boxing the conditions in brackets (), also doesn't help.
  • Workaround - create a simple contains condition for every Tag selected e.g. Tags.Contains("New") OR Tags.Contains("Blah") etc.. But in the real application it results in a really complex / bad query for each condition and kills the performance.

我可能丢失了一些东西,或者这可能是库中的错误.

I might be missing something or this could be a bug in the library.

如果有人可以帮助我,我将非常感激.

I would really appreciate if someone could help me with this.

推荐答案

Found a/the bug in ParseAggregate... The pushing of itouterIt and back doesn't work if there are multiple levels. The code supposes that the it and outerIt won't be changed by a third party before being reset (technically the code isn't reentrant). You can try with other variants of System.Linq.Dynamic (there are like two or three variants out of there). Probably some variants have already fixed it.

或者您可以从链接的站点中获取代码,然后在代码内部对其进行重新编译(最后,原始" System.Linq.Dynamic是单个cs文件),您可以像这样对其进行修补:

Or you can take the code from the linked site and recompile it inside your code (in the end the "original" System.Linq.Dynamic is a single cs file) and you can patch it like this:

Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
{
    // Change starts here
    var originalIt = it;
    var originalOuterIt = outerIt;
    // Change ends here

    outerIt = it;
    ParameterExpression innerIt = Expression.Parameter(elementType, elementType.Name);
    it = innerIt;
    Expression[] args = ParseArgumentList();

    // Change starts here
    it = originalIt;
    outerIt = originalOuterIt;
    // Change ends here

    MethodBase signature;
    if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)

我已经在项目的github中打开了一个带有建议的错误修复的问题.

I've already opened an Issue with the suggested bug fix in the github of the project.

这篇关于使用outerIt生成动态Linq查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆