C# Linq选择所有未找到的Linq
假设我有以下表格:C# Linq选择所有未找到的Linq,c#,.net,linq,C#,.net,Linq,假设我有以下表格: class Module { long MID // PK string Name } class ModuleBlock { long MID // FK long BID // FK } class Block { long BID // PK string Info } 我想选择ModuleBlock中没有出价的所有块 如何进行此查询 我很确定这是一种类似于BID上带有Module
class Module
{
long MID // PK
string Name
}
class ModuleBlock
{
long MID // FK
long BID // FK
}
class Block
{
long BID // PK
string Info
}
我想选择ModuleBlock中没有出价的所有块
如何进行此查询
我很确定这是一种类似于BID上带有ModuleBlock的连接块并检查空值的方法,但我如何在LINQ中做到这一点?不确定“空值”,因为您在伪代码中没有提供任何可空值属性。但是LINQ查询可能是这样的,我认为:
List<Module> modules = ...
List<ModuleBlock> moduleBlocks = ...
List<Block> blocks = ...
var blocksWithNoBidsInModuleBlocks = blocks
.Where(b => !moduleBlocks.Select(mb => mb.BID).Contains(b.BID)).ToList();
列出模块=。。。
列表moduleBlocks=。。。
列表块=。。。
var blocksWithNoBidsInModuleBlocks=块
.Where(b=>!moduleBlocks.Select(mb=>mb.BID).Contains(b.BID)).ToList();
由于您在伪代码中没有提供任何可为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();
列出模块=。。。
列表moduleBlocks=。。。
列表块=。。。
var blocksWithNoBidsInModuleBlocks=块
.Where(b=>!moduleBlocks.Select(mb=>mb.BID).Contains(b.BID)).ToList();
如果您愿意在客户端执行此操作,而不是将其转换为SQL,则可以修改此方法以处理两种不同类型的序列
然后你可以打电话
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);
}
}
私有静态IEnumerable ExceptByImpl(
这是第一次,
我数不清的秒,
Func键选择器源,
Func键选择器秒,
IEqualityComparer(键盘比较器)
{
HashSet key=新的HashSet(
第二个。选择(按键选择器第二个),
键比较器);
foreach(第一个变量元素)
{
TKey=keySelectorSource(元素);
if(key.Contains(key))
{
继续;
}
收益-收益要素;
key.Add(key);
}
}
如果您愿意在客户端执行此操作,而不是将其转换为SQL,则可以修改此方法以处理两种不同类型的序列
然后你可以打电话
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);
}
}
私有静态IEnumerable ExceptByImpl(
这是第一次,
我数不清的秒,
Func键选择器源,
Func键选择器秒,
IEqualityComparer(键盘比较器)
{
HashSet key=新的HashSet(
第二个。选择(按键选择器第二个),
键比较器);
foreach(第一个变量元素)
{
TKey=keySelectorSource(元素);
if(key.Contains(key))
{
继续;
}
收益-收益要素;
key.Add(key);
}
}
这里有一个非常简单的方法,只使用连接即可完成此操作:
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;
第二个查询为您提供了所需的结果。这里有一个相当简单的方法,可以仅使用联接来完成此操作:
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;
第二个查询提供您想要的结果。这是Linq到实体/Linq到SQL吗?这是Linq到实体/Linq到SQL吗?