web-dev-qa-db-ja.com

Linq to SQLの実行方法「[where] [column] in(value of list)」

IDのリストを取得する関数があり、IDに関連付けられている説明に一致するリストを返す必要があります。例えば。:

public class CodeData
{
    string CodeId {get; set;}
    string Description {get; set;}
}

public List<CodeData> GetCodeDescriptionList(List<string> codeIDs)
    //Given the list of institution codes, return a list of CodeData
    //having the given CodeIds
}

したがって、このために自分でsqlを作成している場合は、次のようなことを行うだけです(in節にはcodeIds引数のすべての値が含まれます)。

Select CodeId, Description FROM CodeTable WHERE CodeId IN ('1a','2b','3')

Linq to Sqlでは、 "IN"句に相当するものが見つからないようです。私がこれまでに見つけた最高の(それは機能しません):

 var foo = from codeData in channel.AsQueryable<CodeData>()
           where codeData.CodeId == "1" || codeData.CodeId == "2"
           select codeData;

問題は、コンパイル時に設定されるため、linq to sqlの「OR」句のリストを動的に生成できないことです。

Linq to Sqlを使用して、値の動的リスト内の列をチェックするwhere句をどのように実現しますか?

92
Nathan

つかいます

where list.Contains(item.Property)

またはあなたの場合:

var foo = from codeData in channel.AsQueryable<CodeData>()
          where codeIDs.Contains(codeData.CodeId)
          select codeData;

ただし、ドット表記で行うこともできます。

var foo = channel.AsQueryable<CodeData>()
                 .Where(codeData => codeIDs.Contains(codeData.CodeId));
153
Jon Skeet

以下も使用できます。

List<int> codes = new List<int>();

codes.add(1);
codes.add(2);

var foo = from codeData in channel.AsQueryable<CodeData>()
          where codes.Any(code => codeData.CodeID.Equals(code))
          select codeData;
25
Nick DeMayo

Jon Skeetの答えでメソッドを使用していましたが、Concatを使用して別のメソッドが発生しました。 Concatメソッドは、限られたテストでわずかに優れたパフォーマンスを発揮しましたが、面倒なので、おそらくContainsに固執するか、これを行うためのヘルパーメソッドを作成します。いずれにせよ、誰かが興味を持っている場合の別のオプションがあります:

方法

// Given an array of id's
var ids = new Guid[] { ... };

// and a DataContext
var dc = new MyDataContext();

// start the queryable
var query = (
    from thing in dc.Things
    where thing.Id == ids[ 0 ]
    select thing 
);

// then, for each other id
for( var i = 1; i < ids.Count(); i++ ) {
    // select that thing and concat to queryable
    query.Concat(
        from thing in dc.Things
        where thing.Id == ids[ i ]
        select thing
    );
}

性能試験

これは、科学的なものではありませんでした。データベース構造とリストに含まれるIDの数が大きな影響を与えると思います。

ConcatContainsをそれぞれ100回試行するテストをセットアップしました。各試行では、主キーのランダム化リストで指定された25行を選択しました。これを約12回実行し、ほとんどの場合、Concatメソッドは5〜10%高速になりますが、一度だけContainsメソッドがsmidgenによって勝ちました。

1
DCShannon
 var filterTransNos = (from so in db.SalesOrderDetails
                    where  ItemDescription.Contains(ItemDescription)
                            select new { so.TransNo }).AsEnumerable();    


listreceipt = listreceipt.Where(p => filterTransNos.Any(p2 => p2.TransNo == p.TransNo)).ToList();
0
Deepan Raj