在LINQ中,哪种方法更好?

4
我正在使用C#中的LINQ,并有一个快速的问题。
在这里我展示了非常少量的代码,在实时操作中还有一些排序操作。我想知道在下面的代码中,我应该使用哪种方法?? 方法1
 public class UserDetails
    {
        private dbContext db = new dbContext();
        public List<User> ActiveUser()
        {
          return db.Users.Where(m => m.Active == true).ToList();                   
        }
        public List<User> InActiveUser()
        {
          return db.Users.Where(m => m.Active == false).ToList();                   
        }
       
    }

方法2

 public class UserDetails
    {
       List<Defect> allUser = new db.Users.ToList();
        public List<User> ActiveUser()
        {
          return allUser.Where(m => m.Active == true).ToList();                   
        }
        public List<User> InActiveUser()
        {
          return allUser.Where(m => m.Active == false).ToList();                   
        }
       
    }

有超过20种方法来获取数据,每种方法都从同一张表中获取数据,但使用不同的where条件。 我的问题是:我应该创建dbContext并在每个方法中使用单独的查询(方法1),还是应该创建一个列表,并在方法自身中使用where条件筛选所有数据(方法2)。


6
始终在数据源处进行过滤。在第二种方法中,如果您有2000万个用户会发生什么?所有这些记录都将被获取到内存中,然后在内存中进行过滤,这对性能来说非常糟糕。 - Igor
1
  1. 研究使用依赖注入,它可以管理实例的生命周期,包括释放资源(在禁用类型上调用Dispose)。然后,类型“UserDetails”将具有一个构造函数,该构造函数接受类型“DbContext”并使用它。
- Igor
@Igor 我认为每次调用数据库会给服务器带来更多的负担。 - Sudhir Dehade
2
第一种方法更好,因为1)您只会按请求实现数据2)可能会有其他线程更新数据库中的数据。使用第二种方法,您永远不会获得此更新。 - Aleks Andreev
1
第二种方法的另一个问题是您的记录将变得陈旧。如果某些内容更新了用户的活动状态,但您仍在处理拉入列表中的旧状态,会发生什么情况?基本上,您希望尽可能少地提取几条记录,然后可以实现某种类型的缓存(如果需要),在此期间您可以控制在获取新鲜数据之前在内存中保留数据的时间。 - juharr
显示剩余5条评论
3个回答

6
它取决于情况。一般而言,我更喜欢方法1,因为通常无法预测数据库中有多少用户,并且将所有用户拉入内存会导致大量的内存开销。此外,对于大量用户,您将利用数据库优化,例如索引和查询执行计划。
如果我们谈论少量用户,则方法2可能更具性能,因为它减少了与数据库的通信次数。但是除了内存开销之外,它还存在其他问题,例如缓存用户和缺少数据库更新。
然而,我几乎总是更喜欢方法1,因为最好在数据库上完成大部分筛选和排序工作,因为它已经针对此类操作进行了优化。使用方法2,随着用户基础随着时间的推移增长,您可能会遇到缓存或内存问题很难追踪。此外,如果您没有非常恶劣的连接或多次执行此操作,则一次或两次数据库通信的差异大多可以忽略不计。

这要看具体情况。我们在哪里可以找到准确的数学公式?我的意思是,x数量的数据需要多少内存,并且一个请求需要多长时间来完成,它们之间有什么关系呢? - Sudhir Dehade
3
99.999%的情况下,你应该使用方法1 @SudhirDehade。如果方法1很慢,那么可以考虑使用方法2。但始终要从方法1开始。在你现阶段,我建议总是使用方法1,不要担心其他的。 - mjwills
1
@mjwills所说的是你应该采取的方法。如果你想要精确的数字,你需要为你的具体情况编写性能测试,使用自动数据种子,这样你就可以准确地看到不同数据大小对性能和内存使用的影响。然而,只要你没有明显的性能问题,让你的代码尽可能简单、稳定/易于出错的方法比计算人工数字要容易得多,因为你无法预知网络速度或用户数量等实际经验。 - Christoph Sonntag

3

不要加载不必要的数据。在方法2中,您加载了不必要的数据。


1

我个人更倾向于第一种方法,因为在第一种方法中,从数据库获取过滤数据,而在第二种方法中,则是先获取所有数据,然后在框架层面进行过滤,而不是在数据库层面进行过滤。因此,在第一种方法中,我们可以获得性能上的好处。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接