web-dev-qa-db-ja.com

Linqの複数のWHERE句

私はLINQが初めてなので、複数のwhere句を実行する方法を知りたいです。これが私が達成したいことです。特定のユーザー名を除外してレコードを返します。以下のコードを試しましたが、期待どおりに動作しませんでした。

DataTable tempData = (DataTable)grdUsageRecords.DataSource;
var query = from r in tempData.AsEnumerable()
            where ((r.Field<string>("UserName") != "XXXX") || (r.Field<string>("UserName") != "XXXX"))                            
            select r;    

            DataTable newDT = query.CopyToDataTable();

事前に助けてくれてありがとう!!!

70
Ganesha

まあ、複数の "where"句を直接入れることができますが、私はそうは思わないと思います。複数の「where」節が最終的にmore制限フィルターになります-less制限的なもの。本当に欲しいと思う:

DataTable tempData = (DataTable)grdUsageRecords.DataSource;
var query = from r in tempData.AsEnumerable()
            where r.Field<string>("UserName") != "XXXX" &&
                  r.Field<string>("UserName") != "YYYY"
            select r;

DataTable newDT = query.CopyToDataTable();

||の代わりに&&に注意してください。ユーザー名がXXXXでなくユーザー名がYYYYではない場合、行を選択します。

編集:コレクション全体がある場合は、さらに簡単です。コレクションの名前がignoredUserNamesであるとします:

DataTable tempData = (DataTable)grdUsageRecords.DataSource;
var query = from r in tempData.AsEnumerable()
            where !ignoredUserNames.Contains(r.Field<string>("UserName"))
            select r;

DataTable newDT = query.CopyToDataTable();

Containsの呼び出しに時間がかかるのを避けるために、これをHashSet<string>にしたいのが理想ですが、コレクションが十分に小さければ、それほど大きな違いはありません。

109
Jon Skeet

@テオ

LINQトランスレーターは、次を実行するのに十分スマートです。

.Where(r => r.UserName !="XXXX" && r.UsernName !="YYYY")

私はこれをLinqPadでテストしました==>はい、Linqトランスレータは十分に賢いです:))

39
alex

@Jon:Jon、複数のwhere句を使用して言っていますか?.

var query = from r in tempData.AsEnumerable()
            where r.Field<string>("UserName") != "XXXX" 
            where r.Field<string>("UserName") != "YYYY"
            select r;

使用するよりも制限的です

var query = from r in tempData.AsEnumerable()
            where r.Field<string>("UserName") != "XXXX" && r.Field<string>("UserName") != "YYYY"
            select r;

結果が出る限り、それらは同等だと思います。

ただし、最初の例の複数の場所を使用して2つのサブクエリ、つまり.Where(r=>r.UserName!="XXXX").Where(r=>r.UserName!="YYYY)またはLINQトランスレータが.Where(r=>r.UserName!="XXXX" && r.UsernName!="YYYY")を実行するのに十分スマートである場合、テストしていません

19

また、boolメソッドを使用できます

クエリ:

DataTable tempData = (DataTable)grdUsageRecords.DataSource;
var query = from r in tempData.AsEnumerable()
            where isValid(Field<string>("UserName"))// && otherMethod() && otherMethod2()                           
            select r;   

        DataTable newDT = query.CopyToDataTable();

方法:

bool isValid(string userName)
{
    if(userName == "XXXX" || userName == "YYYY")
        return false;
    else return true;
}
6
Tolga Okur