Итак, у меня есть три таблицы:
CREATE TABLE tblUser
(
[pkUserID] [int] IDENTITY(1,1) NOT NULL,
[userName] [varchar](150) NULL,
[fkCompanyID] [int] NOT NULL
)
CREATE TABLE tblCompany
(
[pkCompanyID] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](255) NULL
)
CREATE TABLE tblSystem
(
[pkSystemID] [int] IDENTITY(1,1) NOT NULL,
[systemName] [varchar](150) NULL,
[fkCompanyID] [int] NULL
)
Это мои объекты передачи данных:
public class SystemDTO
{
public int pkSystemId { get; set; }
public string Name { get; set; }
public int? fkCompanyId { get; set; }
}
public class CompanyDTO
{
public int pkCompanyId { get; set; }
public string Name { get; set; }
public IEnumerable<SystemDTO> Systems { get; set; }
}
public class UserDTO
{
public int pkUserId { get; set; }
public string Name { get; set; }
public IEnumerable<CompanyDTO> Companies { get; set; }
}
Это запрос Linq, который я пытаюсь сделать:
var result= (
from user in db.tblUsers
select new UserDTO()
{
pkUserId=user.pkUserID,
Name=user.realName,
Companies=
(
from company in db.tblCompanies
where user.fkCompanyID==company.pkCompanyID
select new CompanyDTO()
{
pkCompanyId=company.pkCompanyID,
Name=company.name,
Systems=
(
from system in db.tblSystem
where system.fkCompanyId==company.pkCompanyId
select new SystemDTO()
{
pkSystemId=system.pkSystemID,
Name=system.systemName,
fkCompanyId=system.fkCompanyID
}
)
}
)
}
).ToList();
Проблема этого запроса в том, что самый внутренний запрос
from system in db.tblSystem
where system.fkCompanyId==company.pkCompanyId
select new SystemDTO()
{
pkSystemId=system.pkSystemID,
Name=system.systemName,
fkCompanyId=system.fkCompanyID
}
заставляет linq переводить sql в один выбор для объекта. Я знаю, что могу пропустить выбор и зациклить результат и установить свойство. Как это:
var lsSystem= db.tblSystem.Select (s =>new SystemDTO(){pkSystemId=s.pkSystemID,Name=s.systemName,fkCompanyId=s.fkCompanyID}).ToList();
foreach (var user in result)
{
foreach (var company in user.Companies)
{
company.Systems=lsSystem.Where (a =>a.fkCompanyId==company.pkCompanyId).ToList();
}
}
Это заставит linq делать два выбора, а не по одному на объект. Так что теперь к моим вопросам. Есть ли другой способ сделать это? Могу ли я заполнить внутреннюю коллекцию по-другому?
Любое предложение будет оценено
EDIT
Было предложено использовать loadoption. Я не могу найти вариант загрузки между системой и компанией. Но я могу включить loadoption между. Компания и пользователь, как это:
var option=new DataLoadOptions();
option.LoadWith<tblCompany>(a=>a.fkCompanytblUsers);
db.LoadOptions=option;
Но это не влияет на запрос, который все еще переводится на многие выборки
EDIT2
Как сказано в комментариях к ответам, параметры загрузки не применяются для этого типа запроса linq.