簡體   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