正在开发一个越来越复杂的ViewModel / PresentationModel。
我希望Linq查询返回IQueryable<UserPresentationModel>
对MSSQL使用EntityFramework
是否可以在将其返回到表示层之前对集合进行任何类型的迭代,即
List<UserPresentationModel> list = new List<UserPresentationModel>();
foreach (var person in listOfPeople)
{
UserPresentationModel u = new UserPresentationModel();
int userUIStatus = GetColourStateOfPerson(person);
u.FirstName = person.FirstName;
u.UserUIStatus = userUIStatus;
list.Add(u);
}
return list
这感觉它总是N + 1,我永远不会得到延迟执行,查询组成的优势..
或者(我想回答我自己的问题)我是否需要以基于SQL集的方式思考。
答案 0 :(得分:0)
使用IEnumerable<T>.Aggregate()
代替循环。
return listOfPeople.Aggregate(new List<UserPresentationModel>(), person => {
return new UserPresentationModel {
FirstName = person.FirstName,
UserUIStatus = GetColourStateOfPerson(person)
};
}).AsQueryable();
答案 1 :(得分:0)
首先,我们可以将您的代码转换为LINQ。
IEnumerable<UserPresentationModel> models =
from person in listOfPeople
select new UserPresentationModel
{
FirstName = person.FirstName,
UserUIStatus = GetColourStateOfPerson(person)
}
return models.ToList();
现在,如果GetColourStateOfPerson
正在进行数据库往返,那么你肯定想把它拉出来。
IDictionary<int, int> colourStatesByPersonId = GetColourStatesOfPeople(listOfPeople);
IEnumerable<UserPresentationModel> models =
from person in listOfPeople
select new UserPresentationModel
{
FirstName = person.FirstName,
UserUIStatus = colourStatesByPersonId[person.PersonId]
}
return models.ToList();
你可能设法创建一个LINQ查询,它只能在一个查询中获取你想要的人的名字和颜色状态,但是你没有提供足够的关于你的数据上下文的信息来帮助你这一点。
我个人会避免绕过IQueryable,这可能会在有人触摸它时继续进行数据库访问。让您的数据层获取您可能需要的所有数据,将其组合成一个列表,然后返回。
答案 2 :(得分:0)
return listOfPeople.AsEnumerable().Select(p =>
new UserPresentationModel
{
FirstName = p.FirstName,
UserUIStatus = GetColourStateOfPerson(p)
}).AsQueryable();
我假设listOfPeople
是最终将针对您的数据库执行的IQueryable
。如果是这种情况,那么AsEnumerable()
很重要,因为SQL Server不知道如何处理GetColourStateOfPerson()
。 AsEnumerable()
将强制IQueryable
的表达式树执行,将结果行从数据库中拉出,然后在代码中应用Select()
转换,而不是在SQL Server中。
如果您可以将GetColourStateOfPerson()
实现为存储过程或数据库功能,那么您可以省略AsEnumerable()
和AsQueryable()
并允许执行延迟更长时间。