寻求有关我的 LINQ 表达式设计的反馈 [关闭]

Posted

技术标签:

【中文标题】寻求有关我的 LINQ 表达式设计的反馈 [关闭]【英文标题】:Seeking feedback on my design of LINQ expressions [closed] 【发布时间】:2014-07-31 21:09:09 【问题描述】:

场景:我有一个在 .NET 4.5 上使用 EF 6.1 和 SQL Server 2012 的 Windows 控制台应用程序。

问题:我想得到一些反馈,以下哪个 LINQ 表达式是从数据库加载数据的首选方式或更有效的方式:

    // Option 1: Using List<>
    public List<Employee> EmployeeList 
    
         get  return Context.Employees.Select(e => e).ToList(); 
    

    // Option 2: Using IList<>
    public IList<Employee> EmployeeList2
    
         get  return Context.Employees.Select(e => e).ToList(); 
    

    // Option 3: Using IEnumerable<>
    public IEnumerable<Employee> EmployeeList3
    
         get  return Context.Employees.Select(e => e); 
    

    // Option 4: Using IQueryable
    public IQueryable<Employee> EmployeeList4
    
         get  return Context.Employees.Select(e => e); 
    

    // Option 5: Using IQueryable & AsNoTracking()
    public IQueryable<Employee> EmployeeList5
    
         get  return Context.Employees.Select(e => e).AsNoTracking(); 
    

    // Option 6: Using "async/await"
    public async Task<List<Employee>> GetEmployeeList6()
    
         return await Context.Employees.Select(x => x).ToListAsync(); 
    

   // Option 7: Using "using" statement
    public List<Employee> GetEmployeeList7()
    
         using (Context context = new Context())
         
             return Context.Employees.Select(e => e).ToList();
         
     

请注意,我不需要 EF 来跟踪任何更改。我只需要将员工列表放入内存中以便我可以操作它们,这就是我将扩展方法 AsNoTracking() 添加到选项 5 的原因。

【问题讨论】:

自己进行基准测试。可能会有无法估量的差异。在您的Select 之后返回IEnumerable&lt;T&gt; 的那些将是最快的,因为由于延迟执行,它们实际上并没有做任何事情。此外,using 的最后一个“选项”实际上并没有使用在 using 块中声明的变量。 【参考方案1】:

你在比较苹果和橘子。您列出的每种方法都有优点和缺点,因此无法回答哪种方法是“首选方法”。

同样,这些示例中的许多将立即返回,因为它们使用延迟执行,因此它们在技术上会运行得更快,但实际上不会让您的程序运行得更快。

但是,如果您只是想获取所有员工的内存列表,并且您不关心更改跟踪,正如您所说,我更喜欢这样:

public IReadOnlyCollection<Employee> EmployeeList

     get  return Context.Employees.AsNoTracking().ToList(); 

您不需要.Select(e =&gt; e):它没有任何作用。 AsNoTracking() 会给你带来轻微的性能提升。 .ToList() 确保在方法返回之前将值实际加载到内存中。 我个人喜欢使用IReadOnlyCollection&lt;&gt;s,当我想表明我正在提供已加载到内存中的内容时,但我不想给人这样的印象,即使用代码会从我归还的收藏。

【讨论】:

很好的反馈!很高兴了解这些要点,尤其是关于 IReadOnlyCollection,我什至没有考虑过。

以上是关于寻求有关我的 LINQ 表达式设计的反馈 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

是否应该使用 Linq? [关闭]

C#将字典的LINQ查询重构为单个lambda表达式[关闭]

我的数据库连接是否关闭? (Linq to Sql)

哪本书是学习 Linq 的最佳书籍,包括 Linq to Entities? [关闭]

如何将复杂的 linq 映射到对象

寻求有关如何从特定数组中获取所有过滤列表的帮助