为什么在这里使用tolist()不是一个好方法?

时间:2015-05-12 11:37:47

标签: c# linq entity-framework

这不是一个好方法......!谁能说出原因?

var dbc= new SchoolContext();
var a=dbc.Menus.ToList().Select(x=> new {
                             x.Type.Name,
                             ListOfChildmenus = x.ChildMenu.Select(cm=>cm.Name),
                             ListOfSettings = x.Settings.SelectMany(set=>set.Role)
                                         });

2 个答案:

答案 0 :(得分:5)

因为当您调用.ToList().FirstOrDefault()等等(当您枚举时),您的查询将会被执行。

所以,当你执行dbc.Menus.ToList()时,你会从数据库中获取所有菜单的内存,而你却不希望如此。

您只想将您选择的内容(子菜单列表和设置列表)引入内存。

相关的进一步阅读:http://www.codeproject.com/Articles/652556/Can-you-explain-Lazy-Loading - 可能你正在使用延迟加载

如果你想为你的IQueryable添加一个过滤器,你可能会读到有关可怜的,可疑的http://blog.micic.ch/net/iqueryable-vs-ienumerable-vs-ihaveheadache

之间的区别

还有一些dinamic过滤https://codereview.stackexchange.com/questions/3560/is-there-a-better-way-to-do-dynamic-filtering-and-sorting-with-entity-framework

答案 1 :(得分:1)

实际上Razvan的回答并不完全准确。你的查询中会发生什么:

  1. 当你调用ToList()时,整个表的内容会被转储到内存中。

  2. 当您访问ChildMenuSettings 等导航属性时,会为该表格中的每个元素生成并运行新查询

    < / LI>

    如果你这样做的话:

    dbc.Menus
    .Select(x=> new {
        x.Type.Name,
        ListOfChildmenus = x.ChildMenu.Select(m=>m.Name),
        ListOfSettings = x.Settings.SelectMany(z=>z.Role)
    })
    .ToList()
    

    您的整个结构将在一次查询和一次往返数据库中生成。

    另外,正如亚历克斯在评论中所说,这不一定是坏方法。例如,如果您的数据库负载很大,那么将内容放入Web应用程序的内存并在那里使用它们有时会更好。