System.Linq.Dynamicを使用して、動的な「where」式でエンティティをクエリします。文字列型のプロパティ「newValue」を持つオブジェクトをクエリしています。値の例は、「{\ "ProcessId \":764、\ "ProcessLength \":1000}」です。残りの文字列に関係なく、プロパティに "ProcessId:764"が含まれるすべてのヒットを検索するため、==を使用できません。問題は、格納された文字列にエスケープ記号 "\"と二重引用符が含まれており、正確にどのようになるかがわからないことです。
dbContext.Processes.Where("@newValue.Contains(\"ProcessId\":764\")")
はエラーになりますが、 dbContext.Processes.Where("@newValue.Contains(\":764\")")
機能します私のクエリにはバックスラッシュまたは二重引用符が含まれている必要があると思いますが、自分でそれを理解することはできません。
ここで注意すべき点が2つあります。
コンパイル時にクエリの対象となる列(つまり、 newValue
)がわかっている場合は、標準のLinqを使用するだけです: var list = items.Where(i => i.NewValue.Contains("904")).ToList()
。
dyanmic Linqを使用する場合は、通常、 Where("SomeColumn.Contains("something")")
やWhere("SomeColumn.Contains(@0)", new string[] {"something"})
列にWhere
を適用しますWhere("SomeColumn.Contains(@0)", new string[] {"something"})
。
したがって、あなたの場合、これはうまくいくはずです: items.Where("newValue.Contains(\"904\")")
。
@newValue
は文字列リテラルとして解析されるため、 Where("@newValue.Contains("something")")
しても意味がありません。同様の質問に関するこのコメントも参照してください。
ここに簡単な例があります:
public static void Main(string[] args)
{
var items = new []
{
new { Id = "1", Title = "ProcessId: 123"},
new { Id = "4", Title = "ProcessId: 456"},
new { Id = "7", Title = "ProcessId: 789"},
}.ToList();
// returns null, because the string "Title" doesn't contain the string "7"
var res1 = items.Where("@0.Contains(\"7\")", new string[] {"Title"}).FirstOrDefault();
// works - returns the 3rd element of the array
var res2a = items.Where("Title.Contains(@0)", new string[] {"ProcessId: 789"}).FirstOrDefault();
var res2b = items.Where("Title.Contains(\"ProcessId: 789\")").FirstOrDefault();
}
@HeyJude努力をありがとう、しかし私はそれをうまく動かすことができません。それはどういうわけか間違ってしまった今、私はProcessId番号だけを与える正しい行をフェッチすることさえできません。
私のセットアップの詳細な説明をさせてください。データベースには、列「NewValue」を持つテーブルがあります。この列を使用して、オブジェクトProcessなどのオブジェクトの現在の(テーブルに行を作成するときの)json文字列を格納します。そのため、列には、たとえば{"ProcessId":904、 "ProcessLength":1000}の文字列が格納されます。 dbからこのデータをフェッチするには、テーブルのレコードのコレクションを作成しますvar items = (from l in db.JDE_Logs join u in db.JDE_Users on l.UserId equals u.UserId join t in db.JDE_Tenants on l.TenantId equals t.TenantId where l.TenantId == tenants.FirstOrDefault().TenantId && l.Timestamp >= dFrom && l.Timestamp <= dTo orderby l.Timestamp descending select new //ExtLog { LogId = l.LogId, TimeStamp = l.Timestamp, TenantId = t.TenantId, TenantName = t.TenantName, UserId = l.UserId, UserName = u.Name + " " + u.Surname, Description = l.Description, OldValue = l.OldValue, NewValue = l.NewValue });
。次に、指定したProcessId番号に一致する行を見つけるためにクエリを実行します。例: query = "@NewValue.Contains(\"904,)\")"; items = items.Where(query);
これにより、NewValue列にクエリ文字列が含まれるすべてのレコードがフェッチされますが、これは機能しません。それはコンパイルして「機能する」が、フェッチされない、またはフェッチされないのは、文字列内で904が後に現れるレコードだけです。ばかげて聞こえるかもしれませんが、これはそれです。
"ProcessId":904
を含むすべてのレコードをフェッチするには、クエリ文字列はどのように見えるべきですか?