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

C# 寻求对我的LINQ表达式设计的反馈,c#,performance,linq,entity-framework,async-await,C#,Performance,Linq,Entity Framework,Async Await,场景:我在.NET 4.5上有一个Windows控制台应用程序,使用EF 6.1和SQL Server 2012 问题:我想得到一些反馈,以下哪种LINQ表达式是从数据库加载数据的首选方式或更有效的方式: // Option 1: Using List<> public List<Employee> EmployeeList { get { return Context.Employees.Select(e => e).T

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

问题:我想得到一些反馈,以下哪种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();
         }
     }
//选项1:使用列表
公开名单雇员名单
{
获取{return Context.Employees.Select(e=>e.ToList();}
}
//选项2:使用IList
公共IList员工名单2
{
获取{return Context.Employees.Select(e=>e.ToList();}
}
//选项3:使用IEnumerable
公共IEnumerable EmployeeList3
{
获取{return Context.Employees.Select(e=>e);}
}
//选项4:使用IQueryable
公共可招聘员工名单4
{
获取{return Context.Employees.Select(e=>e);}
}
//选项5:使用IQueryable和AsNoTracking()
公共可招聘员工名单5
{
获取{return Context.Employees.Select(e=>e).AsNoTracking();}
}
//选项6:使用“异步/等待”
公共异步任务GetEmployeeList6()
{
return wait Context.Employees.Select(x=>x.toListSync();
}
//选项7:使用“Using”语句
公共列表GetEmployeeList7()
{
使用(上下文=新上下文())
{
返回Context.Employees.Select(e=>e.ToList();
}
}

请注意,我不需要EF来跟踪任何更改。我只需要将员工列表存入内存,以便对其进行操作,因此我在选项5中添加了扩展方法AsNoTracking()。

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

类似地,这些示例中的许多都会立即返回,因为它们使用延迟执行,所以从技术上讲,它们会运行得更快,但实际上不会使程序运行得更快

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

public IReadOnlyCollection<Employee> EmployeeList
{
     get { return Context.Employees.AsNoTracking().ToList(); }
}
公共IReadOnlyCollection员工列表
{
获取{return Context.Employees.AsNoTracking().ToList();}
}
  • 您不需要
    。选择(e=>e)
    :它什么都不做
  • AsNoTracking()
    将使您的性能略有提高
  • .ToList()
    确保在方法返回之前将值实际加载到内存中
  • 我个人喜欢使用
    IReadOnlyCollection
    s来表示我正在提供一些已加载到内存中的内容,但我不想给人这样的印象,即使用代码会在我返回的集合中添加/删除值

自己进行基准测试。可能会有无法估量的差异。在
Select
之后返回
IEnumerable
的将是最快的,因为由于延迟执行,它们实际上什么都不做。另外,您最后一个使用
using
的“选项”实际上没有使用
using
块中声明的变量。非常好的反馈!很高兴了解这些要点,尤其是关于IReadOnlyCollection,我甚至没有考虑过。