2011-08-01 18 views
1

私は、SQLインジェクション攻撃に対して何らかの保護を提供するために、テキストフィールドへのユーザーの入力に応じて作成されたクエリを書き直しています。動的Linqの作成

SELECT DISTINCT (FileNameID) FROM SurNames WHERE Surname IN 
('Jones','Smith','Armitage') 
AND FileNameID IN (SELECT DISTINCT (FileNameID) FROM FirstNames WHERE FirstName 
IN ('John','William')) 

このプロセスには他のテーブルが最大3つあります。 パラメータリストは最大50〜100エントリであるため、パラメータ化されたクエリの作成は面倒で面倒です。

私は必要な保護を提供し、パラメータ化を処理する必要があるLinqクエリを作成しようとしています。

これは私が必要なものを私に与え

var surnameValues = new[] { "Jones","Smith","Armitage" }; 
    var firstnameValues = new[] { "John","William" }; 

    var result = (from sn in db.Surnames 
       from fn in db.FirstNames 
       where surnameValues.Contains(sn.Surname) && 
       firstnameValues.Contains(fn.FirstName) 
       select fn.FileNameID).Distinct().ToArray(); 
私は今動的に姓やfirstnameのテキスト入力ボックスに、ユーザーが選択したかどうか/入力された値に応じて、これを作成する方法が必要

任意のポインタは感謝して、クエリにすべてのロジックを組み合わせることができ

おかげ ロジャー

答えて

1

を受信します。

var surnameValues = new[] { "Jones","Smith","Armitage" }; 
var firstnameValues = null; 

// Set these two variables to handle null values and use an empty array instead 
var surnameCheck= surnameValues ?? new string[0]; 
var firstnameCheck= firstnameValus ?? new string[0]; 

var result = (from sn in db.Surnames 
      from fn in db.FirstNames 
      where 
      (!surnameCheck.Any() || surnameCheck.Contains(sn.Surname)) && 
      (!firstnameCheck.Any() || firstnameCheck.Contains(fn.FirstName)) 
      select fn.FileNameID).Distinct().ToArray(); 

あなたのクエリは、SurnamesテーブルとfirstNamesテーブルの間の結合条件を持っていないようですか?

(あなたは私がSelectManyを使用しました参加交差やっているように見えるよう)あなたが動的にクエリを構築することができ

var query=db.Surnames.SelectMany(sn=>db.FirstNames.Select (fn => new {fn=fn,sn=sn})); 
if (surnameValues!=null && surnameValues.Any()) query=query.Where(x=>surnameValues.Contains(x.sn.Surname)); 
if (firstnameValues !=null && firstnameValues.Any()) query=query.Where(x=>firstnameValues.Contains(x.fn.FirstName)); 
var result=query.Select(x=>x.fn.FileNameID).Distinct(); 
+0

おかげでボブは、それは非常に便利です。私は部分的にそのルートを下っていたが、あなたがテーブルのいくつかが参加していないと彼らがLinqで行う方法を簡単に見つけることができなかった完全な参加が必要であることを指摘したときに苦労した。私が持っていた主な問題は、where節が追加されていない場合のテーブルの宣言にありました。つまり、ユーザーは姓のみを選択するため、firstname修飾子はwhereクエリーに追加されません。 あなたの例とSelectManyの使用は、本当の目玉でした - 多くのありがとう。 – RogerDodge

+0

あなたが[LinqPad](http://www.linqpad.net)を見れば、あなたのlinqクエリ用のラムダ構文を与えることができ、クロスジョインに同じ選択肢を与えることができます。多くの時間を節約することができます –

+0

私はLinqPadで簡単に見ました - 私は本当にbenfitする有料版が必要ですか? は、使用が選択されなかったため、配列に値が設定されていない場合、Nullとは別の問題が発生しました。 どこ&& が例外をスローします(surnameValues.Any()|| surnameValues.Contains (sn.Surname)!)( (fn.FirstName)firstnameValues.Any()|| firstnameValues.Contains!) - I追加しようとしました firstnameValues == null || where句では動作しませんか? – RogerDodge