如何将这个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" ), 你添加了Tabletable )而不是Referencerefer

这意味着如果一个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); } } } } 

好。 所以我们得到了:

  1. 枚举 – 简单 – 这就是我们开始的地方
  2. 条件检查 – 我们需要一个Where
  3. 枚举另一个集合 – SelectMany
  4. 条件检查 – 再次
  5. 添加 – 最有可能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"));