Linq: результаты проекта

#linq #linq-to-sql #.net-3.5

#linq #linq-to-sql #.net-3.5

Вопрос:

В принципе, у меня много компаний, у которых может быть много офисов, как мне получить мой запрос, чтобы показать это, у меня есть: проблема (или мне так кажется), я получаю компанию 3 раза (пример ниже), когда я должен получать только одну компанию и много офисов,мой запрос просто неверен?

 //companies = _repo.All<Companies>();
//mainoffice = _repo.All<Office>();

        var dto = companies
           .Join(mainoffice, x => x._ID, y => y.CompanyID, (x, y) => new
            {
                mycompany = x,
                myoffice = y,
            })
            .Select(x => new
                {
                    ID = x.mycompany._ID,
                    Offices = x.myoffice
                }); 
  

введите описание изображения здесь

Однако, если я присоединюсь к группе, я получу то, что хочу, но я возвращаю компании, у которых нет офисов…

   var dto = companies
           .GroupJoin(mainoffice, x => x._ID, y => y.CompanyID, (x, y) => new
            {
                mycompany = x,
                myoffice = y,
            })
            .Select(x => new
                {
                    ID = x.mycompany._ID,
                    Offices = x.myoffice
                }); 
  

Обновление: еще 1 вложенный результирующий набор…

         var areascovered = repo.All<OfficePostCode>();

        var filter = repo.All<PostCodeDistrict>()
            .Where(x => x.Region.StartsWith(postcode))
            .Join(areascovered, x => x.PostCodeID, y => y.PostCodeID, (x, y) =>
                 new
                 {
                     Postcode = x.PostCode,
                     Region = x.Region,
                     OfficeID = y.OfficeID
                 });

        var mainoffice = repo.All<Office>();

        var dto = companies
            .Select(company => new
            {
                ID = company._ID,
                Offices = mainoffice.Select(office => new
                {
                    CompanyID = office.CompanyID,
                    Name = office.Name,
                    Tel = office.Tel,
                    RegionsCovered = filter.Where(f => f.OfficeID == office.OfficeID)
                })
                .Where(y => y.CompanyID == company._ID)// amp;amp; y.RegionsCovered.Any())
            })
            .Where(pair => pair.Offices.Any());
  

Ответ №1:

Вам не нужно соединение, вам просто нужен вложенный выбор. Вместо этого попробуйте что-то вроде этого:

 from company in companies
select new
{
   ID = company._ID,
   Offices = mainoffice.Where(office => office.CompanyID == company._ID)
}
  

Если вам не нужны записи с компаниями без офисов, попробуйте это:

 from company in companies
let offices = mainoffice.Where(office => office.CompanyID == company._ID)
where offices.Any()
select new
{
   ID = company._ID,
   Offices = offices
}
  

Явная лямбда-версия (точечная нотация):

Первый:

 companies.Select(company => new
{
    ID = company._ID,
    Offices = mainoffice.Where(office => office.CompanyID == company._ID)
});
  

Компании, не имеющие офисов, удалены:

 companies.Select(company => new
{
    ID = company._ID,
    Offices = mainoffice.Where(office => office.CompanyID == company._ID)
})
.Where(pair => pair.Offices.Any());
  

Комментарии:

1. @lasseepeholt — есть ли версия для lamdba этого?

2. @Haroon Вот так 🙂 Я не тестировал это, но я думаю, что это подойдет.

3. На самом деле оба они являются лямбда, первый — синтаксис запроса, а второй — точечная нотация.

4. @SaeedAmiri Да, но я думаю, все знают, что означает Харун. Но имя изменено 🙂

5. @lasseespeholt — если бы я хотел выбрать другой вложенный результат, я сделал то же самое, что и выше, однако, когда я проверил сгенерированный им sql, не похоже, что это был всего один вызов, возможно ли сделать это одним вызовом? Итак, для офисов у меня есть регионы

Ответ №2:

Нет необходимости объединять компанию с office, в таком объединении вы видите каждую компанию как количество офисов, которые у нее есть, я думаю, вы можете попробовать ниже:

 companies.SelectMany(x=>x.Offices).Select(x=>new {ID = x.CompanyID, Office = x})
  

Или

 offices.GroupBy(x=>x.CompanyID).Select( x=>new {ID = Key, Offices = x});
  

Я предположил, что у вас есть идентификатор компании в каждом офисе.

если вы также хотите иметь полную компанию, вы можете сделать

 var officeGroups = 
    offices.GroupBy(x=>x.CompanyID).Select( x=>new {ID = Key, Offices = x});

var result = from c in companies
               join o in officeGroups on c.ID equals o.ID
               select new {Company = c, Offices = o.Offices};
  

Комментарии:

1. в вашем первом примере, что такое Office, вы имеете в виду mainoffice? Кроме того, использование вашего примера приведет к тому, что я потеряю ссылку на компании

2. @Haroon Я думаю, у вас есть стол для вашего офиса, я прав? office ссылается на эту таблицу.

3. Фактически, оба примера приводят к тому, что я теряю ссылку на компании , мне нужны компании , поскольку они содержат другую информацию, которую мне нужно спроецировать в пользовательский интерфейс

4. Я думаю, что мой второй пример лучше для вас.

5. @Haroon в вашем примере, который вы проецируете на свой идентификатор компании, вы хотите иметь compeletly companies?