Linq策略为复杂集

时间:2013-01-03 18:34:41

标签: sql linq entity-framework

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

3 个答案:

答案 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()并允许执行延迟更长时间。