2017-04-07 11 views
0

私は実行時にいくつかのクエリを生成するためにMicrosoftのダイナミックLinq(System.Linq.Dynamic)ライブラリを使用しています。これは私のためにはうまくいきましたが、1つの特定のシナリオで役に立ちました。outerItを使用して動的Linqクエリを生成

簡略化されたシナリオ - ユーザーが選択したいくつかの特定のタグを持ち、残高がある数よりも大きいクレームをすべて照会しようとしています。

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; } 
} 

このクエリは、エラーがスローされます。

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パーサーは、タグのないクレームオブジェクトのバランスプロパティを見つけようとしているようです。

  • 私はそれは、動的LINQのでキーワード、outerIt、innerItで遊ぶことを試みたが、それのどれも動いていないようにみえます。
  • 実際のアプリケーションでは、フィルタ、演算子、パターンは動的(エンドユーザによって設定)になるため、シーケンスを変更することはできますが、それは私の選択肢ではありません。
  • ブラケット()内の条件をボクシングも助けにはなりません。
  • 回避策 - 選択されたすべてのタグに対して単純な包含条件を作成します。実際のアプリケーションでは、それぞれの条件に対して実際に複雑な/悪いクエリが発生し、パフォーマンスが低下します。

私は何かが不足している可能性があります。これはライブラリに不具合がある可能性があります。

誰かが私に助けてくれたら本当にありがたいです。

+0

どこで、どの文書へのリンクを、このような構文を学びましたか? –

+0

これは私の出発点でした:https://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library。それから私は参照を得たから他のSOの質問があった:http://stackoverflow.com/questions/37740409/c-sharp-dynamiclinq-where-clause-with-any –

+0

私が理解するから、 Linq/EFは、少しの構文上の違いがある動的なlinqに対してすべきです。 –

答えて

1

ParseAggregateのバグが見つかりました。複数のレベルがある場合は、itouterItのプッシュとは動作しません。コードはitouterItがリセットされる前に第三者によって変更されることはないと想定しています(技術的にはコードはリエントラントではありません)。 System.Linq.Dynamicの他の亜種を試すことができます(そこには2つまたは3つの亜種があります)。おそらくいくつかの亜種が既にそれを修正しているでしょう。

それとも、リンク先サイトからコードを取ると、あなたのコード内でそれを再コンパイルし(最終的には「オリジナル」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に提案されているバグ修正の問題を開いています。

+0

ファイルを修正してパッチを適用し、それが解決するかどうかをお知らせします。どうもありがとう。 –

+0

それは動作します。ありがとうございました。私は文脈全体で修正プログラムの性質を理解していないので、この修正プログラムの影響が何であるかはわかりません。今後のリリースで修正されるようにgithubリポジトリに不具合を記録することは意味がありますか? –

+0

@AmanvirSinghMundra 2分前投稿を更新しました:*プロジェクトのギブスで提案されているバグ修正を含む問題を既に開いています。* – xanatos

関連する問題