2

我正在开发一个越来越复杂的 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 集的方式进行思考。

4

3 回答 3

0

使用IEnumerable<T>.Aggregate()而不是循环。

return listOfPeople.Aggregate(new List<UserPresentationModel>(), person => {
    return new UserPresentationModel {
         FirstName = person.FirstName,
         UserUIStatus = GetColourStateOfPerson(person)
    };
}).AsQueryable();
于 2013-01-03T18:47:55.173 回答
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,它可以在任何人触摸它时继续进行数据库旅行。让您的数据层获取您可能需要的所有数据,将其组合成一个列表,然后返回。

于 2013-01-03T18:49:01.473 回答
0
return listOfPeople.AsEnumerable().Select(p => 
    new UserPresentationModel
    {
        FirstName = p.FirstName,
        UserUIStatus = GetColourStateOfPerson(p)
    }).AsQueryable();

我假设这listOfPeopleIQueryable最终将针对您的数据库执行的。如果是这种情况,那么AsEnumerable()很重要,因为 SQL Server 不知道如何处理GetColourStateOfPerson(). AsEnumerable()将强制执行IQueryable' 表达式树,将结果行从数据库中拉出,然后Select()在代码中应用与 SQL Server 相反的转换。

如果您可以实现GetColourStateOfPerson()为存储过程或数据库函数,那么您可以省略AsEnumerable()AsQueryable()允许执行延迟更长时间。

于 2013-01-03T18:51:04.180 回答