英文:
Convert SQL stored procedure to Linq
问题
以下是翻译好的内容:
我创建了以下的存储过程:
PROCEDURE [dbo].[LeadScoring_CountClosedActions]
(@UserId INT,
@StartDate INT,
@EndDate INT)
AS
BEGIN
SET NOCOUNT ON
SELECT TOP 1
COUNT(l.Extra) OVER () AS TotalRecords
FROM
[dbo].[LeadScoringActions] AS a
INNER JOIN
[dbo].[LeadScoringLeads] AS l ON a.LeadId = l.LeadId
WHERE
a.AssignedToUserId = @UserId
AND a.DateCompleted > DATEADD(DAY, @StartDate, GETDATE())
AND a.DateCompleted <= DATEADD(DAY, @EndDate, GETDATE())
AND a.ActionResultType != 'System Closed'
AND l.Extra IS NOT NULL
GROUP BY
l.Extra
END
而我尝试使用以下的EF Core代码来执行它:
var count = await _context.Database.ExecuteSqlRawAsync($"exec LeadScoring_CountClosedActions @UserId={userId}, @StartDate={request.StartDate}, @EndDate={request.EndDate}");
但它总是返回-1,所以我看了一下,似乎我应该将存储过程转换为Linq(参见[此问题的一条评论](https://stackoverflow.com/questions/70822830/ef-6-core-exec-proc-stock-with-count-returning-int))。
我想知道如何做到这一点 - 我知道如何做一般的部分:
var count = await _context
.Actions
.Include(a => a.Lead)
.CountAsync(a => a.ActionResultType != LeadScoringConstants.SystemClosed &&
a.DateCompleted > DateTime.Today.AddDays(request.StartDate) &&
a.DateCompleted <= DateTime.Today.AddDays(request.EndDate) &&
a.AssignedToUserId == userId &&
a.Lead.Extra != null);
但我不确定如何做`GROUP BY`部分 - 在Linq中,它将按`a.Lead.Extra`进行分组,或者是否可以执行`COUNT OVER`?
是将其作为Linq更好,还是有一种执行存储过程并获取正确结果的方法?
英文:
I created the following stored procedure:
PROCEDURE [dbo].[LeadScoring_CountClosedActions]
(@UserId INT,
@StartDate INT,
@EndDate INT)
AS
BEGIN
SET NOCOUNT ON
SELECT TOP 1
COUNT(l.Extra) OVER () AS TotalRecords
FROM
[dbo].[LeadScoringActions] AS a
INNER JOIN
[dbo].[LeadScoringLeads] AS l ON a.LeadId = l.LeadId
WHERE
a.AssignedToUserId = @UserId
AND a.DateCompleted > DATEADD(DAY, @StartDate, GETDATE())
AND a.DateCompleted <= DATEADD(DAY, @EndDate, GETDATE())
AND a.ActionResultType != 'System Closed'
AND l.Extra IS NOT NULL
GROUP BY
l.Extra
END
And I was trying to execute it with the following in EF Core:
var count = await _context.Database.ExecuteSqlRawAsync($"exec LeadScoring_CountClosedActions @UserId={userId}, @StartDate={request.StartDate}, @EndDate={request.EndDate}");
But it was always returning -1 so I had a look around and it would seem I should convert the stored procedure to Linq (see one of the comments on this question)
I was wondering how I would do that - I know how to do the general bits:
var count = await _context
.Actions
.Include(a => a.Lead)
.CountAsync(a => a.ActionResultType != LeadScoringConstants.SystemClosed &&
a.DateCompleted > DateTime.Today.AddDays(request.StartDate) &&
a.DateCompleted <= DateTime.Today.AddDays(request.EndDate) &&
a.AssignedToUserId == userId &&
a.Lead.Extra != null);
But I'm not sure how to do the GROUP BY
- in the linq, it would be grouped by a.Lead.Extra
or if it's possible to do a COUNT OVER
?
Is it better to do it as linq or is there a way to execute the stored procedure and get the correct result?
答案1
得分: 0
最终,我使用LINQ解决了这个问题,通过从数据库中获取匹配的操作,然后获取结果中的不同额外属性并计数它们:
var actions = await _context
.Actions
.Include(a => a.Lead)
.Where(a =>
a.ActionResultType != LeadScoringConstants.SystemClosed &&
a.DateCompleted > DateTime.Today.AddDays(request.StartDate) &&
a.DateCompleted <= DateTime.Today.AddDays(request.EndDate) &&
a.AssignedToUserId == userId &&
a.Lead.Extra != null)
.ToListAsync();
var projectIds = actions.Select(a => a.Lead.Extra).Distinct().Count();
根据评论,我可以将其更改为LINQ:
var count = await _context
.Actions
.Where(a =>
a.ActionResultType != LeadScoringConstants.SystemClosed &&
a.DateCompleted > DateTime.Today.AddDays(request.StartDate) &&
a.DateCompleted <= DateTime.Today.AddDays(request.EndDate) &&
a.AssignedToUserId == userId &&
a.Lead.Extra != null)
.Select(a => new { a.Lead.Extra, a.DateCompleted })
.Distinct()
.CountAsync();
英文:
In the end I solved it using linq by getting the matching actions from the db then I got the distinct extra properties from the results and counted them:
var actions = await _context
.Actions
.Include(a => a.Lead)
.Where(a =>
a.ActionResultType != LeadScoringConstants.SystemClosed &&
a.DateCompleted > DateTime.Today.AddDays(request.StartDate) &&
a.DateCompleted <= DateTime.Today.AddDays(request.EndDate) &&
a.AssignedToUserId == userId &&
a.Lead.Extra != null)
.ToListAsync();
var projectIds = actions.Select(a => a.Lead.Extra).Distinct().Count();
As per comments, I can change this to be done in linq:
var count = await _context
.Actions
.Where(a =>
a.ActionResultType != LeadScoringConstants.SystemClosed &&
a.DateCompleted > DateTime.Today.AddDays(request.StartDate) &&
a.DateCompleted <= DateTime.Today.AddDays(request.EndDate) &&
a.AssignedToUserId == userId &&
a.Lead.Extra != null)
.Select(a => new { a.Lead.Extra, a.DateCompleted })
.Distinct()
.CountAsync();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论