寻求有关我的 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<T>
的那些将是最快的,因为由于延迟执行,它们实际上并没有做任何事情。此外,using
的最后一个“选项”实际上并没有使用在 using
块中声明的变量。
【参考方案1】:
你在比较苹果和橘子。您列出的每种方法都有优点和缺点,因此无法回答哪种方法是“首选方法”。
同样,这些示例中的许多将立即返回,因为它们使用延迟执行,因此它们在技术上会运行得更快,但实际上不会让您的程序运行得更快。
但是,如果您只是想获取所有员工的内存列表,并且您不关心更改跟踪,正如您所说,我更喜欢这样:
public IReadOnlyCollection<Employee> EmployeeList
get return Context.Employees.AsNoTracking().ToList();
您不需要.Select(e => e)
:它没有任何作用。
AsNoTracking()
会给你带来轻微的性能提升。
.ToList()
确保在方法返回之前将值实际加载到内存中。
我个人喜欢使用IReadOnlyCollection<>
s,当我想表明我正在提供已加载到内存中的内容时,但我不想给人这样的印象,即使用代码会从我归还的收藏。
【讨论】:
很好的反馈!很高兴了解这些要点,尤其是关于 IReadOnlyCollection,我什至没有考虑过。以上是关于寻求有关我的 LINQ 表达式设计的反馈 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
C#将字典的LINQ查询重构为单个lambda表达式[关闭]