如何将这个foreach循环转换为Linq代码?
我是Linq的新手,我想修改旧的c#代码以使用Linq。 这段代码的想法是选择所有未设置的表和引用的字段PrimaryTable等于“myTable”
foreach (Table table in dbServer.Tables) { if (!table.IsSet) { foreach (Reference refer in table.References) { if (refer.PrimaryTable == "myTable") { tables.Add(table); } } } }
在互联网上挖掘后我得到了这段代码
var q = from table in dbServer.Tables let refers = from refer in table.References where refer.PrimaryTable == "myTable" select refer.ForeignTable where refers.Contains(table.Name) select table;
var q = from table in dbServer.Tables let refers = from refer in table.References where refer.PrimaryTable == "myTable" select refer.ForeignTable where refers.Contains(table.Name) select table;
但它根本不起作用,我需要你的帮助才能使它有效。
提前致谢。
var tables = dbServer.Tables .Where(t => !t.IsSet) .SelectMany(t => t.References) .Where(r => r.PrimaryTable == "myTable") .ToList();
假设表是List
编辑:正如评论指出的那样,这与原版不一样 – 看起来你真正想要的是这个:
var tables = dbServer.Tables .Where(t => !t.IsSet && t.References.Any(r => r.PrimaryTable == "myTable")) .ToList();
这将为您提供所有具有PrimaryTable为’myTable’的引用的表,该表假定只有一个匹配的引用表。 否则,您可以多次添加相同的表。
只需要使用两个来自
var q = from table in dbServer.Tables where !table.IsSet from refer in table.References where refer.PrimaryTable == "myTable" select table;
编辑
实际上,我对这段代码感到有点困惑。 你确定它正在做它的意图吗? 特别是,让我失望的是你正在枚举table.References
,但是当某个条件适用于特定的Reference
(即, refer.PrimaryTable == "myTable"
), 你添加了Table
( table
)而不是Reference
( refer
) 。
这意味着如果一个Table
有多个具有PrimaryTable == "myTable"
Reference
对象, PrimaryTable == "myTable"
tables
集合可能包含该Table
多个副本。 它是否正确?
我打算走出困境,并猜测你真正要检查的只是一个Table
在其References
集合中有任何带有PrimaryTable == "myTable"
Reference
对象。 如果是这种情况,在tables.Add(table)
之后的原始代码中,我会简单地添加break
来避免重复。 (可能每个集合中只有一个Reference
具有相同的PrimaryTable
,在这种情况下你会没事;但是你仍然可以在这一点上停止枚举。除非你想要复制品。)
无论如何,Lee的代码(以及我在下面提到的代码)并没有重复这种行为。 相反,它将Reference
对象添加到列表中(因为最终的ToList
调用在IEnumerable
)。
看来,如果我上面描述的是你所追求的行为,你可能想要这样做:
var tables = dbServer.Tables .Where(table => !table.IsSet) .Where( table => table.References.Any(refer => refer.PrimaryTable == "myTable") ).ToList();
原始答案
我将扩展Lee的答案。 让我们逐行分析。
// 1. enumerating over a collection foreach (Table table in dbServer.Tables) { // 2. checking a condition if (!table.IsSet) { // 3. enumerating over another collection foreach (Reference refer in table.References) { // 4. checking a condition if (refer.PrimaryTable == "myTable") { // 5. adding to a collection tables.Add(table); } } } }
好。 所以我们得到了:
- 枚举 – 简单 – 这就是我们开始的地方
- 条件检查 – 我们需要一个
Where
- 枚举另一个集合 –
SelectMany
- 条件检查 – 再次
- 添加 – 最有可能
ToList
(取决于您想要的集合类型)
这是它的结果:
var tables = dbServer.Tables // step 1 .Where(table => !table.IsSet) // step 2 .SelectMany(table => table.References) // step 3 .Where(refer => refer.PrimaryTable == "myTable") // step 4 .ToList(); // step 5
合理?
tables.AddRange(dbServer.Tables .Where(t => !t.IsSet) .SelectMany(t => table.References) .Where(r => r.PrimaryTable == "myTable"));