场景:我使用带有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中。
答案 0 :(得分:1)
你在比较苹果和橘子。您列出的每种方法都有其优点和缺点,因此无法回答哪种方式是“首选方式”。
同样,这些示例中的许多将立即返回,因为它们使用延迟执行,因此它们在技术上运行得更快,但实际上不会使程序运行得更快。
但是,如果您只是想获取所有员工的内存列表,并且您不关心更改跟踪,正如您所说,我更喜欢这个:
public IReadOnlyCollection<Employee> EmployeeList
{
get { return Context.Employees.AsNoTracking().ToList(); }
}
.Select(e => e)
:它不会做任何事情。 AsNoTracking()
会给您带来轻微的性能提升。 .ToList()
确保在方法返回之前将值实际加载到内存中。 IReadOnlyCollection<>
,当我想表明我提供的东西已被加载到内存中时,但我不想给人的印象是消费代码应该添加/删除值来自我回归的藏品。