假设我有以下表格:
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连接块并检查空值但是如何在LINQ中执行此操作?
答案 0 :(得分:1)
由于您未在伪代码中提供任何可为空的属性,因此不确定'nulls'。但是我认为LINQ查询可能是这样的:
List<Module> modules = ...
List<ModuleBlock> moduleBlocks = ...
List<Block> blocks = ...
var blocksWithNoBidsInModuleBlocks = blocks
.Where(b => !moduleBlocks.Select(mb => mb.BID).Contains(b.BID)).ToList();
答案 1 :(得分:1)
如果您乐意在客户端执行此操作而不是将其转换为SQL,则可以修改MoreLinq's ExceptBy
方法以处理两种不同类型的序列。
然后你可以打电话
var modulelessBlocks =
allBlocks.Except(
allModuleBlocks,
block => block.MID,
moduleblock => moduleblock.MID);
这样做的好处是只能迭代每个源一次。
以下是修改过的迭代器的示例 - 您必须修改其他方法以匹配:
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);
}
}
答案 2 :(得分: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;
第二个查询为您提供所需的结果。