1

次のコード ブロック (C#) を使用している場合:

var query = context.Set.Where(o => o.Email.Contains("Mail@gmail.com"));
var stringQuery = ((System.Data.Objects.ObjectQuery)query).ToTraceString();

linq は次のクエリを生成します。

SELECT *
FROM [SET] AS [Extent1]
WHERE [Extent1].[Email] LIKE '%Mail@gmail.com%'

次のコード ブロックを使用している場合:

string email = "Mail@gmail.com";
var query = context.Set.Where(o => o.Email.Contains(email));
var stringQuery = ((System.Data.Objects.ObjectQuery)query).ToTraceString();

linq は次のクエリを生成します。

SELECT *
FROM [Set] AS [Extent1]
WHERE [Extent1].[Email] LIKE @p__linq__0 ESCAPE N'~'

最初のケースのように、文字列をハードコードせずに linq にクエリを生成させ、代わりに文字列パラメーターとして渡すにはどうすればよいですか?

4

1 に答える 1

1

あなたが見た結果は、あるべき姿です。その理由は、Linqは文字列リテラルをハードコードされているものとして正しく識別し、SQLインジェクションとキャプチャの対象ではないと想定します(つまり、定数であり、遅延クエリが実行された時点で異なる値になることはありません)。

同様に、変数が変化する可能性があり、ユーザー入力である可能性があることを正しく識別します。このような場合に推奨/ベストプラクティスであるパラメータ化されたクエリを使用します。

ただし、このベストプラクティスをオーバーライドしたい場合は(よく知っているので?)=)、式ツリーをたどって変数アクセスを見つけ、代わりにノードをConstantExpressionに置き換えることができます。これにより、あなたが観察したように、linqがクエリをハードコーディングするようになると思います。

MSDN-式ツリービジター

VisitMemberAccessメソッドに注意し、ConstantExpressionMemberExpressionを見て ください

于 2012-07-17T09:25:57.090 に答える