Поскольку вы присоединяетесь записи вместе, это утверждение не верно:
Теперь этот результирующий набор будет иметь только один ProcessBases, каждый ProcessBase будет иметь несколько InspectorArticles и каждый InspectorArticle будет иметь несколько InspectorSamples.
То, что вы на самом деле есть после выполнения запроса является IEnumerable
, где каждый объект IEnumerable
содержит ссылку на ProcessBase
, в InspectorArticle
и InspectorSample
. Например, используя приведенный ниже код в LINQPad даст в IEnumerable
со следующим содержанием:
Код:
void Main()
{
var processBases = new List<ProcessBase>();
var inspectorArticles = new List<InspectorArticle>();
var inspectorSamples = new List<InspectorSample>();
processBases.Add(new ProcessBase { ID = 1 });
processBases.Add(new ProcessBase { ID = 2 });
inspectorArticles.Add(new InspectorArticle { ID = 3, ProcessBaseID = 1 });
inspectorArticles.Add(new InspectorArticle { ID = 4, ProcessBaseID = 1 });
inspectorArticles.Add(new InspectorArticle { ID = 5, ProcessBaseID = 2 });
inspectorSamples.Add(new InspectorSample { ID = 6, InspectorArticleID = 3 });
inspectorSamples.Add(new InspectorSample { ID = 7, InspectorArticleID = 3 });
inspectorSamples.Add(new InspectorSample { ID = 8, InspectorArticleID = 3 });
inspectorSamples.Add(new InspectorSample { ID = 9, InspectorArticleID = 4 });
inspectorSamples.Add(new InspectorSample { ID = 10, InspectorArticleID = 5 });
inspectorSamples.Add(new InspectorSample { ID = 11, InspectorArticleID = 5 });
var processBaseID = 1;
var results = from obj1 in processBases
join obj2 in inspectorArticles on obj1.ID equals obj2.ProcessBaseID
join obj3 in inspectorSamples on obj2.ID equals obj3.InspectorArticleID
where obj1.ID == processBaseID
select new { obj1, obj2, obj3 };
Console.WriteLine(results);
}
public class ProcessBase
{
public int ID { get; set; }
}
public class InspectorArticle
{
public int ID { get; set; }
public int ProcessBaseID { get; set; }
}
public class InspectorSample
{
public int ID { get; set; }
public int InspectorArticleID { get; set; }
}
Результаты:
![linqpad results](https://i.stack.imgur.com/EwH3G.jpg)
Итак, если вы хотите сохранить оператор Linq как есть и пропустить его через несколько операторов foreach, вам нужно будет использовать что-то вроде кода belo ш:
foreach(var article in results.GroupBy(g => g.obj2.ID))
{
Console.WriteLine("Article ID: #{0}", article.Key);
foreach(var sample in results
.Where(s => s.obj3.InspectorArticleID == article.Key)
.Select(s => s.obj3))
{
Console.WriteLine("\tSample ID: #{0}", sample.ID);
}
}
Используя этот код (и продолжая пример из выше) вы должны получить выход:
Article ID: #3
Sample ID: #6
Sample ID: #7
Sample ID: #8
Article ID: #4
Sample ID: #9
Недостатком этого подхода является то, что вы испытываете, чтобы перечислить список результатов нескольких раз. Если вы знаете, что этот список всегда будет небольшим, то это не так уж и важно. Если список будет очень большим, тогда вам может потребоваться лучший способ вернуть данные.
EDIT
Чтобы сделать код более эффективным, вы могли бы группировать по InspectorArticle.ID
, а затем создать Dictionary
индексировано по ID
, и содержащий исходный InspectorArticle
и связанный с ним InspectorSamples
.
var articles = results.GroupBy(g => g.obj2.ID)
.ToDictionary(k => k.Key, v => new {
InspectorArticle = v.Select(s => s.obj2).First(),
InspectorSamples = v.Select(s => s.obj3) });
foreach(var article in articles.OrderBy(a => a.Key).Select(kv => kv.Value))
{
Console.WriteLine("Article ID: #{0}", article.InspectorArticle.ID);
foreach(var sample in article.InspectorSamples)
{
Console.WriteLine("\tSample ID: #{0}", sample.ID);
}
}
Код выше даст те же результаты, как мой первый пример, но для более длинных списков статей и образцов будет более эффективным, поскольку он будет только перечислить весь список один раз при создании Dictionary
.
Пожалуйста, обратите внимание, что я ключ к Dictionary
прочь ID
собственности, потому что я не поставлять IEqualityComparer
методы GroupBy
. Если бы вы предпочли ключ от объекта InspectorArticle
, вам нужно убедиться, что два разных экземпляра InspectorArticle
с одинаковыми ID
считаются равными, что можно сделать, если вы создаете IEqualityComparer
и передаете его в метод GroupBy
.
Большое вам спасибо :) –
Рад, что я мог помочь! – rsbarro
@ClunkyCoder Подумал об этом немного больше и разместил более эффективный метод, если у вас есть более длинные списки. – rsbarro