9

免責事項:System.Linq.Expressionsの式を使用して問題を解決しましたが、それでもより良い/より簡単な方法を探しています。

次の状況を考慮してください。

var query = 
    from c in db.Customers
    where (c.ContactFirstName.Contains("BlackListed") || 
           c.ContactLastName.Contains("BlackListed")  ||
           c.Address.Contains("BlackListed"))
    select c;

ブラックリストに登録された用語に対してチェックする必要のある列/属性は、実行時にのみ使用できます。この動的なwhere句を生成するにはどうすればよいですか?

さらに複雑なのは、Queryableコレクション(上記のdb.Customers)が「Customer」(たとえば「Person」)の基本クラスのQueryableに入力されるため、上記のようにc.Addressを書き込むことはオプションではないことです。

4

4 に答える 4

13

@Geoffには、Dynamic LINQを正当化する最良のオプションがあります。

実行時に Lambda を使用してクエリを作成する方法に進みたい場合は、PredicateBuilder ( http://www.albahari.com/nutshell/predicatebuilder.aspx ) を使用し、次のようなものを使用することをお勧めします。

Expression<Fun<T,bool>> pred = null; //delcare the predicate to start with. Note - I don't know your type so I just used T 
if(blacklistFirstName){
  pred = p => p.ContactFirstName.Contains("Blacklisted");
}
if(blacklistLastName){
  if(pred == null){
    pred = p => p.ContactLastName.Contains("Blacklisted"); //if it doesn't exist just assign it
  }else{
    pred = pred.And(p => p.ContactLastName.Contains("Blacklisted"); //otherwise we add it as an And clause
  }
}

含めたいすべての列についても同様です。クエリに到達したら、次のようなものが必要です。

var results = db.Customers.Where(pred).Select(c => c);

これを使用して、約 20 の異なるオプションがあり、非常に優れた SQL を生成する検索用の LINQ を構築しました。

于 2008-10-25T22:30:42.783 に答える
8
var query = from C in db.Customers select c;

if (seachFirstName)
         query = query.Where(c=>c.ContactFirstname.Contains("Blacklisted"));

if (seachLastName)
         query = query.Where(c=>c.ContactLastname.Contains("Blacklisted"));

if (seachAddress)
         query = query.Where(c=>c.Address.Contains("Blacklisted"));

それらは相互に排他的ではないことに注意してください。

于 2008-10-24T17:35:45.913 に答える
2

いくつかの論理式を使用して、where句のオンとオフを切り替えることができます。

//Turn on all where clauses
bool ignoreFirstName = false;
bool ignoreLastName = false;;
bool ignoreAddress = false;

//Decide which WHERE clauses we are going to turn off because of something.
if(something)
    ignoreFirstName = true; 

//Create the query
var queryCustomers = from c in db.Customers 
    where (ignoreFirstName || (c.ContactFirstName.Contains("BlackListed")))
    where (ignoreLastName || (c.ContactLastName.Contains("BlackListed")))
    where (ignoreAddress || (c.Address.Contains("BlackListed"))
    select j;  

クエリでignoreFirstNameがtrueの場合、orステートメントの反対側の条件は無視されます。

于 2012-03-01T12:14:10.180 に答える
0

これは LINQ to Objects ではなく LINQ to SQL であるため、式またはストアド プロシージャを使用する以外に選択肢はありません。

于 2008-10-25T22:19:59.357 に答える