0

次のテーブルがあるとします。

class Module
{
    long MID    // PK
    string Name
}

class ModuleBlock
{
    long MID      // FK
    long BID      // FK
}

class Block
{
    long BID      // PK
    string Info
}

ModuleBlocks に BID がないすべてのブロックを選択したいと考えています。

このクエリを実行するにはどうすればよいですか?

BID でブロックを ModuleBlocks と結合し、null をチェックするという行に沿ったものだと確信していますが、LINQ でこれを行うにはどうすればよいですか?

4

3 に答える 3

1

これを SQL に変換するのではなく、クライアント側で行うことに満足している場合は、2 つの異なる型のシーケンスで動作するようにMoreLinq のメソッドを変更できます。ExceptBy

その後、あなたは呼び出すことができます

var modulelessBlocks =
 allBlocks.Except(
     allModuleBlocks,
     block => block.MID,
     moduleblock => moduleblock.MID);

これには、各ソースを 1 回だけ繰り返すという利点があります。

変更されたイテレータの例を次に示します。一致するように他のメソッドを変更する必要があります。

private static IEnumerable<TSource> ExceptByImpl<TSource, TSecond, TKey>(
    this IEnumerable<TSource> first,
    IEnumerable<TSecond> second,
    Func<TSource, TKey> keySelectorSource,
    Func<TSecond, TKey> keySelectorSecond,
    IEqualityComparer<TKey> keyComparer)
{
    HashSet<TKey> keys = new HashSet<TKey>(
        second.Select(keySelectorSecond),
        keyComparer);
    foreach (var element in first)
    {
        TKey key = keySelectorSource(element);
        if (keys.Contains(key))
        {
            continue;
        }
        yield return element;
        keys.Add(key);
    }
}  
于 2012-08-20T09:00:29.097 に答える
1

結合のみを使用してそれを行うかなり簡単な方法を次に示します。

var bids =
    from m in modules
    join mb in moduleBlocks on m.MID equals mb.MID
    select mb.BID;

var bs =
    from b in blocks
    join bid in bids on b.BID equals bid into gbids
    where !gbids.Any()
    select b;

2 番目のクエリでは、必要な結果が得られます。

于 2012-08-20T09:10:45.223 に答える
1

疑似コードでnull可能なプロパティを指定していないため、「null」についてはわかりません。しかし、LINQクエリは次のようになります/可能性があります:

List<Module> modules = ...
List<ModuleBlock> moduleBlocks = ...
List<Block> blocks = ...

var blocksWithNoBidsInModuleBlocks = blocks
   .Where(b => !moduleBlocks.Select(mb => mb.BID).Contains(b.BID)).ToList();
于 2012-08-20T08:34:45.880 に答える