求我对LINQ表达式设计的反馈

时间:2014-06-10 23:04:24

标签: c# performance linq entity-framework async-await

场景:我使用带有SQL Server 2012的EF 6.1在.NET 4.5上安装了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来跟踪任何更改。我只需要将Employees列表放入内存中,以便我可以操作它们,因此我将扩展方法AsNoTracking()添加到Option 5中。

1 个答案:

答案 0 :(得分:1)

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

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

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

public IReadOnlyCollection<Employee> EmployeeList
{
     get { return Context.Employees.AsNoTracking().ToList(); }
}
  • 您不需要.Select(e => e):它不会做任何事情。
  • AsNoTracking()会给您带来轻微的性能提升。
  • .ToList()确保在方法返回之前将值实际加载到内存中。
  • 我个人喜欢使用IReadOnlyCollection<>,当我想表明我提供的东西已被加载到内存中时,但我不想给人的印象是消费代码应该添加/删除值来自我回归的藏品。