.SelectMany () и получение данных из более чем одной связанной таблицы - PullRequest
5 голосов
/ 01 февраля 2011

Этот запрос возвращает идентификатор сотрудника, имя, идентификатор компании, название компании и город компании. Мне не хватает адреса электронной почты сотрудника (адрес электронной почты хранится в таблице EmployeeEmailAddress) и телефонных номеров сотрудников (номер телефона хранится в таблице EmployeePhoneNumbers).

Мне нужно было добавить .SelectMany (), чтобы получить отношения родительской компании и получить доступ к идентификатору компании, имени и городу. Однако теперь я не могу получить доступ ни к каким свойствам, не найденным в таблице PersonOrgMap. Я не могу перейти к другим таблицам. Удаление .SelectMany () позволяет мне переходить к другим таблицам, но я теряю доступ к информации родительской компании.

var employees = Contacts.Where(c => c.ContactAttributes
.Any (ca => ca.AttributeID == 1153))
.SelectMany (x => x.ChildPersonOrgMaps)
.Select (c => new { employeeId = c.Child.ContactID,
          c.Child.FirstName,
          c.Child.LastName,
          companyId = c.ParentContactID,
          c.Parent.OrganizationName,
          c.Parent.City
        }
         )
.OrderBy (c =>c.LastName ).ThenBy(x => x.FirstName)
.Dump();

Ответы [ 4 ]

16 голосов
/ 26 мая 2011

Если вы заинтересованы в синтаксисе метода, то существует перегрузка в SelectMany (), которая также дает вам доступ как к объектам «источника», так и «результата»:

.SelectMany(x => x.ChildPersonOrgMaps, (x, c) => new { x, c })
.Select(xc => new 
{ 
    xc.x.Attribute1,
    xc.x.Attribute2,
    xc.c.Child.Attribute3,
    xc.c.Attribute4
});
5 голосов
/ 01 февраля 2011

Здесь действительно помогают выражения запросов.Если вы запустите запрос следующим образом:

from c in Contacts
where c.ContactAttributes.Any (ca => ca.AttributeID == 1153))
from om in c.ChildPersonOrgMaps
...

, у вас будет доступ к переменным c и om позже в запросе.C # переводит это в вызов SelectMany, выбирая во временный анонимный тип, который «несет» исходную переменную.Лучший способ убедиться в этом - написать запрос как выражение запроса в LINQPad, а затем посмотреть на лямбда-вкладку, чтобы увидеть перевод в свободный синтаксис.

0 голосов
/ 22 января 2019

Я изучаю LINQ и предпочитаю разделять команды, чтобы я мог знать, что и где происходит. Это, конечно, неэффективно, как принятый ответ, но, вероятно, может пригодиться любому, кто изучает LINQ.

Я предпочитаю демонстрировать на некоторых фиктивных данных

var persons = new [] {"John's", "Mike's", "Albert's"};
var objects = new [] {"car", "house", "bicycle"};
var colors  = new [] {"red", "blue", "green", "yellow"};


var firstPair = persons.SelectMany(_ => objects, (p, o) => new {
   Person = p,
   Object = o
});

var secondPair = firstPair.SelectMany(_ => colors, (fp, c) => new {
   Person = fp.Person,
   Object = fp.Object,
   Color = c
});

Это дает вывод в LINQ Pad, как это. введите описание изображения здесь

0 голосов
/ 01 февраля 2011

Я согласен с Джо Албахари - используйте синтаксис запроса. Это единственное (что мне известно), которое вы можете делать с запросом, а с синтаксисом метода -

.

Вы можете попробовать выбрать анонимный тип, содержащий ваши родительские и дочерние объекты, но я не думаю, что EF это очень понравится.

var employees = Contacts.Where(c => c.ContactAttributes 
.Any (ca => ca.AttributeID == 1153)) 
.SelectMany (x => new { Parent = x, Child = x.ChildPersonOrgMaps })
// etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...