我不知道这是否会成为"因素" LINQ与否。
dbContext.Bills.Select(b => new
{
code = b.Code,
date = b.Date,
weight = b.Package.Weight,
quantity = b.BillRows.Sum(r => (int)r.Quantity) ?? 0,
total = b.Package.Weight * (b.BillRows.Sum(r => (int)r.Quantity) ?? 0),
});
正如您所看到的,投影有两倍的代码:
b.BillRows.Sum(r => (int)r.Quantity) ?? 0
问题:LINQ是否会重复使用第一个结果 - 或 - 它会计算两倍的总和吗?
(*)整个投影转换为SQL,所以这里没有计算内存。
我知道我可以做以下事情(但......有点丑陋/不优雅)
dbContext.Bills.Select(b => new
{
code = b.Code,
date = b.Date,
weight = b.Package.Weight,
quantity = b.BillRows.Sum(r => (int)r.Quantity) ?? 0,
total = 0,
}).Select(b => new
{
code = b.code,
date = b.date,
weight = b.weight,
quantity = b.quantity,
total = b.weight * b.quantity
});
答案 0 :(得分:2)
它会做两次。我做了一个模拟示例总结ID(不想写所有这些类等等);
这是我的疑问:
BookingRequests.Select(br => new {
quantity = br.BookingRequestCalendars.Sum(brc => brc.CalendarID),
total = br.BookingRequestCalendars.Sum(brc => brc.CalendarID) * br.Id
}).Dump();
产生以下SQL:
SELECT (
SELECT SUM([t1].[CalendarID])
FROM [BookingRequestCalendar] AS [t1]
WHERE [t1].[BookingRequestID] = [t0].[Id]
) AS [quantity], ((
SELECT SUM([t2].[CalendarID])
FROM [BookingRequestCalendar] AS [t2]
WHERE [t2].[BookingRequestID] = [t0].[Id]
)) * [t0].[Id] AS [total]
FROM [BookingRequests] AS [t0]
至于性能打击,我无法告诉你。也许数据库会为您优化。我会对这段代码进行一些分析,看看是否值得优化查询
您的第二个查询看起来更好一点:
BookingRequests.Select(br => new {
weight = br.Id,
quantity = br.BookingRequestCalendars.Sum(brc => brc.CalendarID),
total = 0
})
.Select(b => new {
quality = b.quantity,
total = b.weight * b.quantity
})
.Dump();
产地:
SELECT [t2].[value] AS [quality], [t2].[Id] * [t2].[value] AS [total]
FROM (
SELECT [t0].[Id], (
SELECT SUM([t1].[CalendarID])
FROM [BookingRequestCalendar] AS [t1]
WHERE [t1].[BookingRequestID] = [t0].[Id]
) AS [value]
FROM [BookingRequests] AS [t0]
) AS [t2]
回应关于更好的方法的评论,也许是这样的?
BookingRequests.Select(br => new {
quantity = br.BookingRequestCalendars.Sum(brc => brc.CalendarID),
b = br
})
.Select(br => new {
// code = br.b.code,
// date = br.b.date,
quality = br.quantity,
total = br.quantity * br.b.Id
}).Dump();
它提供了这个SQL:
SELECT [t2].[value] AS [quality], [t2].[value] * [t2].[Id] AS [br]
FROM (
SELECT (
SELECT SUM([t1].[CalendarID])
FROM [BookingRequestCalendar] AS [t1]
WHERE [t1].[BookingRequestID] = [t0].[Id]
) AS [value], [t0].[Id]
FROM [BookingRequests] AS [t0]
) AS [t2]
也就是说,将sum作为变量返回,再加上整行。好处是您不必复制其余属性(您只需要填写第二个选项) - 缺点是br.b.Id
看起来不太整洁。这真的是一个偏好问题。我不确定是否有一个非常优雅的解决方案。
另一种选择是编写视图,然后查询该视图。代码看起来可能更好 - 但可能不值得付出努力