我知道这个问题已经有答案了,我同意使用
AsEnumerable()
。然而,我想强调一个常见的场景,我通常会遇到使用
AsEnumerable()
来解决此错误的低效方法。
来自
.NET语言集成查询关系数据:
与ToList()和ToArray()不同,AsEnumerable()运算符不会导致查询执行。它仍然是延迟的。AsEnumerable()运算符仅改变查询的静态类型,将IQueryable转换为IEnumerable,欺骗编译器将其余的查询视为本地执行。
参考文献
- 我是否误解了LINQ to SQL .AsEnumerable()?
- 理解LINQ to SQL中的.AsEnumerable()
低效的方式
IEnumerable<InvoiceDTO> inefficientEnumerable =
(from a in db.Invoices
where a.Practice_Key == practiceKey.FirstOrDefault()
select a
).AsEnumerable().
Select(x => new InvoiceDTO
{
InvoiceID = x.InvoiceID,
PracticeShortName = x.Dim_Practice.Short_Name,
InvoiceDate = x.InvoiceDate,
InvoiceTotal = x.InvoiceAmount,
IsApproved = x.IsApproved,
InvoiceStatus = (
x.IsApproved == null ? "Pending" :
x.IsApproved == true ? "Approved" :
x.IsApproved == false ? "Rejected" : "Unknown"
),
InvoicePeriodStartDateText = x.InvoicePeriodStart.ToShortDateString(),
InvoicePeriodEndDateText = x.InvoicePeriodEnd.ToShortDateString(),
InvoicePeriodStartDate = x.InvoicePeriodStart,
InvoicePeriodEndDate = x.InvoicePeriodEnd
}
);
invoices = inefficientEnumerable.ToList();
在这里,AsEnumerable
被用于整个表格。即使不需要,所有列都被选择了。
更好的方式
IQueryable<InvoiceDTO> invoicesQuery =
(from a in db.Invoices
where a.Practice_Key == practiceKey.FirstOrDefault()
select new InvoiceDTO
{
InvoiceID = a.InvoiceID,
PracticeShortName = a.Dim_Practice.Short_Name,
InvoiceDate = a.InvoiceDate,
InvoiceTotal = a.InvoiceAmount,
IsApproved = a.IsApproved,
InvoiceStatus = (
a.IsApproved == null ? "Pending" :
a.IsApproved == true ? "Approved" :
a.IsApproved == false ? "Rejected" :"Unknown"
),
InvoicePeriodStartDate = a.InvoicePeriodStart,
InvoicePeriodEndDate = a.InvoicePeriodEnd
});
IEnumerable<InvoiceDTO> betterEnumerable = invoicesQuery.AsEnumerable().
Select(x => new InvoiceDTO
{
InvoiceID = x.InvoiceID,
PracticeShortName = x.PracticeShortName,
InvoiceDate = x.InvoiceDate,
InvoiceTotal = x.InvoiceTotal,
IsApproved = x.IsApproved,
InvoiceStatus = x.InvoiceStatus,
InvoicePeriodStartDateText = x.InvoicePeriodStartDate.ToShortDateString(),
InvoicePeriodEndDateText = x.InvoicePeriodEndDate.ToShortDateString(),
InvoicePeriodStartDate = x.InvoicePeriodStartDate,
InvoicePeriodEndDate = x.InvoicePeriodEndDate
}
);
ToList()
- 因为使用AsEnumerable
就可以在减少负载的情况下完成工作,为什么要构建另一个列表呢? - Jon SkeetToList
来返回一个列表 - 调用ToList().Select(...).ToList()
没有任何意义。 - Jon Skeet