動的なlinq式の文字列内に配列を定義するには、どうすれば.Where(string)
渡すことができますか?私はすでに{ "val a", "val b", "val c" }
試しましたが、これは機能しません。
これが私が達成したいことの例です:
public class Person
{
String Name { get; set; }
int Age { get; set; }
}
次に、完全に動的に作成された動的linq式文字列を使用してIQueryable<Person>
にクエリを実行します。たとえば、事前定義された値のリストに対してName
がクエリされます。以下は機能しますが、値が多い場合は面倒です。
myQueryablePersons.Where("Name == \"John Doe\" || Name == \"Mr Smith\" || Name == \"CatWoman\");
私がしたいのは次のようなものです:
myQueryablePersons.Where("{ \"John Doe\", \"Mr Smith\", \"CatWoman\" }.Contains(Name)");
プレーンなC#またはプレーンなLinqを使用してこれをどのように実現できるかは知っていますが、 Where()
渡された文字列のみを使用して実現したいと考えています。これはまったく可能ですか? Stackoverflowや他のサイトで他の回答を既に検索しましたが、私の特定の質問に本当に当てはまる回答は見つかりませんでした。
短い答え:いいえ
長い答え:
私はこのスニペットを機能させました
Int32List("40, 6, 27").Contains(40) == True
public class Int32List : List<int>
{
public Int32List(string arr) : base(arr.Split(',').Select(a => int.Parse(a.Trim())))
{
}
}
(私はparams int []を試しましたが、文字列パーサーはそれが好きではありません)
public static class ExpressionHelper
{
//https://stackoverflow.com/questions/18313362/call-function-in-dynamic-linq
private static bool _utilsAdded = false;
private static void AddUtilites()
{
if (_utilsAdded == true)
return;
_utilsAdded = true;
var type = typeof(DynamicQueryable).Assembly.GetType("System.Linq.Dynamic.ExpressionParser");
FieldInfo field = type.GetField("predefinedTypes", BindingFlags.Static | BindingFlags.NonPublic);
Type[] predefinedTypes = (Type[])field.GetValue(null);
Array.Resize(ref predefinedTypes, predefinedTypes.Length + 1);
predefinedTypes[predefinedTypes.Length - 1] = typeof(Int32List); // Your type
field.SetValue(null, predefinedTypes);
}
}
アクセス可能な型をキャッシュするため、最初のDynamic Linq呼び出しの前にExpressionHelper.AddUtilities()を呼び出すだけです。
あなたの場合、それは
myQueryablePersons.Where("StringList(\"John Doe, Mr Smith, CatWoman\").Contains(Name)")
ただし、この設定では文字列にカンマを含めることはできません。これは、フォークを使用せずに機能させることができた唯一の方法です
また、このページは役に立ちます: https : //github.com/kahanu/System.Linq.Dynamic/wiki/Dynamic-Expressions#operators
配列の要素にアクセスする必要がある場合は、「it」キーワードを使用します
StringList(\"John Doe, Mr Smith, CatWoman\").Any(it == "John Doe") == True