【发布时间】:2021-07-17 21:11:59
【问题描述】:
我有一个非常基本的父子关系。对于我的主页,我只想从 children 表中获取计数。
var assignmenTotal = new AssignmentUser
{
IsSupervisor = supervisor,
AssignmentTotals = (
from a in db.Assignments
where (StartDate.HasValue)
? DbFunctions.TruncateTime(a.CreatedDate) == StartDate
: a.IsArchived == false
orderby a.ID ascending
join b in db.Adjustments on a.ID equals b.AssignmentID
group b by new {a.ID,a.UserName,a.Status,a.CreatedDate,a.IsArchived}
into g
select new AssignmentTotals
{
ID = g.Key.ID,
UserName = g.Key.UserName,
Status = g.Key.Status,
ImportedDate = DbFunctions.TruncateTime(g.Key.CreatedDate),
StartingLocation = (db.Adjustments
.Where(x => x.AssignmentID == g.Key.ID)
.OrderBy(x => x.LocationID)
.Select(x => x.LocationID)
.FirstOrDefault()),
EndingLocation = (db.Adjustments.
Where(x => x.AssignmentID == g.Key.ID)
.OrderByDescending(x => x.LocationID)
.Select(x => x.LocationID)
.FirstOrDefault()),
TotalLocations = g.Count(x => x.LocationID != null),
TotalLicensePlates = g.Count(x => x.ExpectedLicensePlateID != null),
TotalAdjCompleted = g.Count(x => x.Status == "C"),
IsSameUser = (currUser == g.Key.UserName ? true : false),
IsArchived = g.Key.IsArchived
})
.OrderBy(x => x.ID)
.ToList()
};
现在展平的行总数约为 1000,这大约需要 10 秒才能完成。 如果我写一个 SQL 查询
SELECT ID, UserName, Status, b.StartLocation, b.EndLocation, b.TotalLocations,
b.TotalLicensePlates, b.TotalLocations
FROM Assignments a
INNER JOIN(
SELECT AssignmentID,
min(LocationID) as StartLocation, max(LocationID) as EndLocation,
COUNT(CASE WHEN LocationID is NOT NULL THEN 1 ELSE 0 end) AS TotalLocations,
SUM(CASE WHEN ExpectedLicensePlateID IS NOT NULL THEN 1 ELSE 0 END )TotalLicensePlates,
SUM(CASE WHEN Status = 'C' THEN 1 ELSE 0 END )TotalAdjCompleted
FROM dbo.Adjustments
group by AssignmentID
) b on (a.ID = b.AssignmentID)
WHERE convert(date,a.CreatedDate) ='04/23/2021'
这需要不到一秒钟的时间来完成。
我认为我的问题出在 linq COUNT 部分。我试过做一个子查询,但仍然很慢。我认为问题在于 linq 查询将所有数据带到客户端并在客户端完成所有工作,而不是让服务器完成所有工作?
有没有更好的方法来做到这一点?
编辑:我正在使用实体框架,当我检查 SQL 分析器时,SQL 发送非常长且复杂。
【问题讨论】:
-
你在使用实体框架吗?很可能您非常复杂的 LINQ 查询无法转换为单个 SQL 语句,因此它会执行许多昂贵的查询并在内存中执行其余操作。您是否对通信进行了 SQL 配置文件来验证这一点?
-
您好,是的。我正在使用 EF 并检查了 SQL Profiler 并进行了非常长的复杂 SQL 查询。我有什么选择?
-
为什么没有发布EF生成的SQL?
-
我会尽量简化查询。只需选择(也许只是必填字段)父母和他们的孩子。我认为,如果 EF 在性能方面存在问题,那么在此之后执行 .AsEnumerable 并在 C# 中继续进行计数和空值检查会更快。