我知道这并不容易,但我坚持这一点,无法继续前进。 我有这个linq
var resourceItems = queryable
.Select(ri => new ResourceItemDto
{
Id = ri.Id,
CreationDate = ri.CreationDate,
ParentId = ri.FolderId,
Name = ri.Name,
Type = ri.ResourceType,
Url = ri.Url,
Size = ri.Size,
MediaAssetUuid = ri.MediaAssetUuid,
Blob = ri.Blob,
Container = ri.Container,
GroupId = ri.GroupId,
Status = (ResourceItemStatus) ri.Status,
Progress =
ri.EncodingJobs.SelectMany(j => j.EncodingTasks).Any()
? (ri.EncodingJobs.SelectMany(j => j.EncodingTasks).Sum(t => (decimal?) t.Progress)/
ri.EncodingJobs.SelectMany(j => j.EncodingTasks).Count() ?? 0M)
: 0M,
Uuid = ri.Uuid,
CreatedBy =
new UserDto
{
Id = ri.User.Id,
UserName = ri.User.UserName,
FirstName = ri.User.FirstName,
LastName = ri.User.LastName
}
});
现在的任务是将其移动到SP中,我不想接受EF生成的sql,它是笨拙的和机器生成的。
我最终得到了这个:
SELECT
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
--, (sql_expression) AS Progress
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
FROM ResourceItem ri
INNER JOIN ResourceItemsTree rit ON ri.FolderId = rit.Id
INNER JOIN [User] u ON u.Id = ri.CreatedBy
WHERE
ri.IsDeleted = CAST(0 as BIT)
现在我的问题是进度列计算包括一些重复的SelectMany语句,我不知道如何处理它。 任何帮助都非常感谢,伙计们。
有一个EncodingJobs
表,其中有一个FK ResourceItemId(0到很多)到resourceItem表,还有另一个表EncodingTask和一个FK EncodingJobId(相同的0到多个)。
这是EF产生的:
SELECT
[Project4].[Id] AS [Id],
[Project4].[CreationDate] AS [CreationDate],
[Project4].[FolderId] AS [FolderId],
[Project4].[Name] AS [Name],
[Project4].[ResourceType] AS [ResourceType],
[Project4].[Url] AS [Url],
[Project4].[Size] AS [Size],
[Project4].[MediaAssetUuid] AS [MediaAssetUuid],
[Project4].[Blob] AS [Blob],
[Project4].[Container] AS [Container],
[Project4].[GroupId] AS [GroupId],
[Project4].[Status] AS [Status],
CASE WHEN ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[EncodingJob] AS [Extent12]
INNER JOIN [dbo].[EncodingTask] AS [Extent13] ON [Extent12].[Id] = [Extent13].[JobId]
WHERE [Project4].[Id] = [Extent12].[ResourceItemId]
)) THEN CASE WHEN ([Project4].[C1] / CAST( [Project4].[C2] AS decimal(19,0)) IS NULL) THEN cast(0 as decimal(18)) ELSE [Project4].[C3] / CAST( [Project4].[C4] AS decimal(19,0)) END ELSE cast(0 as decimal(18)) END AS [C1],
[Project4].[Uuid] AS [Uuid],
[Project4].[CreatedBy] AS [CreatedBy],
[Project4].[UserName] AS [UserName],
[Project4].[FirstName] AS [FirstName],
[Project4].[LastName] AS [LastName]
FROM ( SELECT
[Project3].[Id] AS [Id],
[Project3].[FolderId] AS [FolderId],
[Project3].[Name] AS [Name],
[Project3].[ResourceType] AS [ResourceType],
[Project3].[Url] AS [Url],
[Project3].[Size] AS [Size],
[Project3].[MediaAssetUuid] AS [MediaAssetUuid],
[Project3].[Status] AS [Status],
[Project3].[CreationDate] AS [CreationDate],
[Project3].[GroupId] AS [GroupId],
[Project3].[Container] AS [Container],
[Project3].[Blob] AS [Blob],
[Project3].[Uuid] AS [Uuid],
[Project3].[CreatedBy] AS [CreatedBy],
[Project3].[UserName] AS [UserName],
[Project3].[FirstName] AS [FirstName],
[Project3].[LastName] AS [LastName],
[Project3].[C1] AS [C1],
[Project3].[C2] AS [C2],
[Project3].[C3] AS [C3],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent10]
INNER JOIN [dbo].[EncodingTask] AS [Extent11] ON [Extent10].[Id] = [Extent11].[JobId]
WHERE [Project3].[Id] = [Extent10].[ResourceItemId]) AS [C4]
FROM ( SELECT
[Project2].[Id] AS [Id],
[Project2].[FolderId] AS [FolderId],
[Project2].[Name] AS [Name],
[Project2].[ResourceType] AS [ResourceType],
[Project2].[Url] AS [Url],
[Project2].[Size] AS [Size],
[Project2].[MediaAssetUuid] AS [MediaAssetUuid],
[Project2].[Status] AS [Status],
[Project2].[CreationDate] AS [CreationDate],
[Project2].[GroupId] AS [GroupId],
[Project2].[Container] AS [Container],
[Project2].[Blob] AS [Blob],
[Project2].[Uuid] AS [Uuid],
[Project2].[CreatedBy] AS [CreatedBy],
[Project2].[UserName] AS [UserName],
[Project2].[FirstName] AS [FirstName],
[Project2].[LastName] AS [LastName],
[Project2].[C1] AS [C1],
[Project2].[C2] AS [C2],
(SELECT
SUM([Extent9].[Progress]) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent8]
INNER JOIN [dbo].[EncodingTask] AS [Extent9] ON [Extent8].[Id] = [Extent9].[JobId]
WHERE [Project2].[Id] = [Extent8].[ResourceItemId]) AS [C3]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[FolderId] AS [FolderId],
[Project1].[Name] AS [Name],
[Project1].[ResourceType] AS [ResourceType],
[Project1].[Url] AS [Url],
[Project1].[Size] AS [Size],
[Project1].[MediaAssetUuid] AS [MediaAssetUuid],
[Project1].[Status] AS [Status],
[Project1].[CreationDate] AS [CreationDate],
[Project1].[GroupId] AS [GroupId],
[Project1].[Container] AS [Container],
[Project1].[Blob] AS [Blob],
[Project1].[Uuid] AS [Uuid],
[Project1].[CreatedBy] AS [CreatedBy],
[Project1].[UserName] AS [UserName],
[Project1].[FirstName] AS [FirstName],
[Project1].[LastName] AS [LastName],
[Project1].[C1] AS [C1],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent6]
INNER JOIN [dbo].[EncodingTask] AS [Extent7] ON [Extent6].[Id] = [Extent7].[JobId]
WHERE [Project1].[Id] = [Extent6].[ResourceItemId]) AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FolderId] AS [FolderId],
[Extent1].[Name] AS [Name],
[Extent1].[ResourceType] AS [ResourceType],
[Extent1].[Url] AS [Url],
[Extent1].[Size] AS [Size],
[Extent1].[MediaAssetUuid] AS [MediaAssetUuid],
[Extent1].[Status] AS [Status],
[Extent1].[CreationDate] AS [CreationDate],
[Extent1].[GroupId] AS [GroupId],
[Extent1].[Container] AS [Container],
[Extent1].[Blob] AS [Blob],
[Extent1].[Uuid] AS [Uuid],
[Extent1].[CreatedBy] AS [CreatedBy],
[Extent2].[UserName] AS [UserName],
[Extent3].[FirstName] AS [FirstName],
[Extent3].[LastName] AS [LastName],
(SELECT
SUM([Extent5].[Progress]) AS [A1]
FROM [dbo].[EncodingJob] AS [Extent4]
INNER JOIN [dbo].[EncodingTask] AS [Extent5] ON [Extent4].[Id] = [Extent5].[JobId]
WHERE [Extent1].[Id] = [Extent4].[ResourceItemId]) AS [C1]
FROM [dbo].[ResourceItem] AS [Extent1]
INNER JOIN [dbo].[User] AS [Extent2] ON [Extent1].[CreatedBy] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[User] AS [Extent3] ON [Extent1].[CreatedBy] = [Extent3].[Id]
WHERE ([Extent1].[IsDeleted] <> cast(1 as bit)) AND ([Extent1].[FolderId] = @p__linq__0)
) AS [Project1]
) AS [Project2]
) AS [Project3]
) AS [Project4]
答案 0 :(得分:1)
你只需要思考你在寻找什么。 在这种情况下,它是每个resourceItem分组的进度/计数总数。
以下内容应该是正确的,但ID可能需要更正! 这使用公用表表达式(SQL Server),但可以很容易地重写为子查询
;WITH prog AS
(
SELECT
ej.ResourceItemId,
SUM(et.Progress) / COUNT(*) AS totalProg
FROM EncodingJobs ej
JOIN EncodingTasks et ON ej.Id = et.EncodingJobId
GROUP BY
ej.ResourceItemId
)
SELECT
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
,ISNULL(prog.totalProg, 0) AS Progress
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
FROM ResourceItem ri
INNER JOIN ResourceItemsTree rit ON ri.FolderId = rit.Id
INNER JOIN [User] u ON u.Id = ri.CreatedBy
LEFT JOIN prog ON ri.Id = prog.ResourceItemId
WHERE
ri.IsDeleted = CAST(0 as BIT)
答案 1 :(得分:1)
那应该是这样的。
如果Progress是一个整数,则将计数转换为十进制,以避免整数除法。如果不是,则可以避免强制转换
SELECT
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
coalesce(sum(et.Progress) / cast(count(*) as decimal(18,2)), 0) AS Progress
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
FROM ResourceItem ri
INNER JOIN ResourceItemsTree rit ON ri.FolderId = rit.Id
INNER JOIN [User] u ON u.Id = ri.CreatedBy
LEFT JOIN EncodingJob ej on ej.ResourceItemId= ri.Id
LEFT JOIN EncodingTask et on et.JobId = ej.Id
WHERE
ri.IsDeleted = 0
group by
ri.Id
,ri.CreationDate
,ri.FolderId
,ri.Name
,ri.ResourceType
,ri.Url
,ri.Size
,ri.MediaAssetUuid
,ri.Blob
,ri.Container
,ri.GroupId
,ri.Uuid
,u.Id AS UserId
,u.UserName
,u.FirstName
,u.LastName
答案 2 :(得分:0)
您可以将SQL Server Profiler附加到我的数据库并运行该应用程序。 SQL Server Profiler将捕获正在数据库上运行的SQL。然后,您可以将该SQL用作存储过程的起点。