【问题标题】:Which approach is better in LINQ?LINQ 中哪种方法更好?
【发布时间】:2019-06-26 11:07:51
【问题描述】:

我在 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 然后在每个方法中使用单独的查询(Approch 1)还是应该创建一个列表并获取所有数据并在方法本身中使用在哪里条件。 (接近 2

【问题讨论】:

  • 1) 始终在数据源处进行过滤。在方法 2 中,如果你有 2000 万用户会发生什么?所有这些记录都将被提取到内存中,然后在内存中进行过滤,这对性能来说是很糟糕的。
  • @Igor 这意味着你说第一种方法比第二种方法好。
  • 2) 研究使用依赖注入,它可以管理实例的生命周期,包括释放资源(在禁用类型上调用 Dispose)。然后UserDetails 类型将有一个构造函数,该构造函数采用DbContext 类型并使用它。
  • 第一种方法更好,因为 1)您仅通过请求实现数据 2)其他线程可能会更新 db 中的数据。使用第二种方法,您将永远无法获得此更新
  • 第二种方法的另一个问题是您的记录会过时。如果某些东西更新了用户的 Active 状态,但您仍然在弄乱您拉入列表的旧状态,会发生什么情况。基本上,您希望尽可能多地提取一些记录,然后您可以实现某种类型的缓存(如有必要),您可以在其中控制在去数据库获取新数据之前将数据保留在内存中的时间。

标签: c# database performance linq


【解决方案1】:

视情况而定。一般来说,我更喜欢方法 1,因为您通常无法预测数据库中有多少用户,并且您会将所有用户拉入内存,这将导致很大的内存开销。此外,对于大量用户,您将利用索引和查询执行计划等数据库优化。

如果我们谈论的是少量用户,则方法 2 可能是性能更高的方法,因为您减少了到数据库的往返次数。但除了内存开销之外,它还存在其他问题,例如缓存用户和缺少数据库更新。

但是,我几乎总是更喜欢方法 1,因为它是对数据库进行大部分过滤和排序工作的好习惯,因为它已针对执行此类操作进行了优化。使用方法 2,随着用户群随着时间的推移而增长,您可能会遇到麻烦,并且很难追踪缓存或内存问题。此外,如果您没有非常糟糕的连接或多次进行数据库往返,那么一次和两次数据库往返之间的差异几乎可以忽略不计。

【讨论】:

  • “视情况而定”我们在哪里可以找到精确的数学计算?我的意思是x数据量需要多少内存以及完成一个请求需要多少时间,它们是如何相关的???
  • 在 99.999% 的情况下,您应该使用方法 1 @SudhirDehade。如果方法 1 很慢,那么考虑方法 2。但始终从方法 1 开始。在您的阶段,我建议始终使用方法 1,不要再担心了。
  • @mjwills 所说的是您应该采取的方法。如果您想要准确的数字,您需要为您的具体情况编写性能测试,使用自动数据种子,您将准确看到不同数据大小的性能和内存使用情况如何变化。但是,只要您没有明显的性能问题,使您的代码尽可能简单和稳定/容易出错的方法比计算不一定代表您的真实世界经验的人工数字容易得多您无法事先知道网络速度或用户数量等信息。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我个人使用第一种方法,因为在第一种方法中,过滤的数据是从数据库中提取的,而在第二种方法中,所有数据都被提取,然后在框架级别而不是数据库级别进行过滤,所以在第一种方法中,我们可以获得性能优势。

    【讨论】:

      猜你喜欢
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      • 2012-02-08
      • 2012-08-02
      相关资源
      最近更新 更多