Как преобразовать этот цикл 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

EDIT: Как отмечается в комментарии, это не то же самое, что оригинал – похоже, что вы действительно хотите:

 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 имеет несколько Reference объектов с PrimaryTable == "myTable" , ваша коллекция tables может содержать несколько копий этой Table . Это правильно?

Я собираюсь выйти на конечность и догадаться, что то, что вы действительно хотите проверить, просто состоит в том, что Table в своей коллекции Reference любой объект Reference с PrimaryTable == "myTable" . Если это так, в вашем исходном коде после tables.Add(table) я бы просто добавил break чтобы избежать дубликатов. (Может быть, только одна Reference в каждой коллекции будет иметь один и тот же PrimaryTable , и в этом случае все будет хорошо, но вы все равно можете перестать перечислять на этом этапе. Если, конечно, вы не захотите дублировать.)

В любом случае код Ли (и то, что у меня ниже) не дублирует это поведение. Скорее, он добавляет объекты Reference в список (поскольку окончательный вызов ToList находится в IEnumerable ).

Похоже, если то, что я описал выше, это поведение, которое вам нужно, вы можете сделать это:

 var tables = dbServer.Tables .Where(table => !table.IsSet) .Where( table => table.References.Any(refer => refer.PrimaryTable == "myTable") ).ToList(); 

ОРИГИНАЛЬНЫЙ ОТВЕТ

Я собираюсь расширить ответ Ли. Давайте проанализируем это по строкам.

 // 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. Проверка состояния – нам понадобится место
  3. Перечисление над другой коллекцией – SelectMany
  4. Проверка состояния – Where снова
  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"));