繁体   English   中英

使用outerIt生成动态Linq查询

[英]Generate Dynamic Linq query using outerIt

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

简化方案-我正在尝试查询所有索赔,这些索赔具有用户选择的某些特定标签并且其余额大于某个数字。

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'的未处理异常附加信息:类型'String'中不存在属性或字段'Balance'

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

  • 我试过在Dynamic Linq中使用externalIt,innerIt,It关键字,但是似乎都不起作用。
  • 更改顺序是可行的,但这不是我的选择,因为在实际应用中,过滤器,运算符和模式将是动态的(由最终用户配置)。
  • 将条件放在方括号()中也无济于事。
  • 解决方法-为选定的每个标签创建一个简单的包含条件,例如,Tags.Contains(“ New”)或Tags.Contains(“ Blah”)等。但是在实际应用中,这会导致对每个条件的查询非常复杂/错误破坏了表演。

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

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

发现A /臭虫ParseAggregate ...的推动itouterIt和回来,如果有多个级别不起作用。 该代码假定itouterIt不会在重置之前被第三方更改(从技术上讲该代码不可重入)。 您可以尝试使用System.Linq.Dynamic其他变体(那里有两个或三个变体)。 可能有一些变体已将其修复。

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

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中打开了一个带有建议的错误修复的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM