我使用LinqPad编写了LINQ查询,以返回应该检索调查问卷邀请的用户。查询运行正常并返回正确的结果。
但是我需要以SQL形式提供此查询。当我单击LinqPad中的SQL按钮时,它返回SQL表单,但每个单独的记录都有一个单独的select语句。请允许我使用2000行的SQL查询。
这是我的LINQ查询
var result2 = AI_Conversations
.Where(f => f.End_DateTime.Value.Date == DateTime.Now.AddDays(-1).Date).GroupBy(f => f.Email)
.Where(f => f.GroupBy(z => z.Chatbot_Name).Count() == 1)
.ToList().Select(f =>
new
{
Name = f.LastOrDefault().Disp_Name,
f.LastOrDefault().Email,
Reference = f.LastOrDefault().Report_ConvNumber
});
result2.Dump();
在SQL中返回以下内容
-- Region Parameters
DECLARE @p0 DateTime = '2017-06-07 00:00:00.000'
DECLARE @p1 Int = 1
-- EndRegion
SELECT [t1].[Email] AS [Key]
FROM (
SELECT [t0].[Email]
FROM [AI_Conversations] AS [t0]
WHERE CONVERT(DATE, [t0].[End_DateTime]) = @p0
GROUP BY [t0].[Email]
) AS [t1]
WHERE ((
SELECT COUNT(*)
FROM (
SELECT NULL AS [EMPTY]
FROM [AI_Conversations] AS [t2]
WHERE ((([t1].[Email] IS NULL) AND ([t2].[Email] IS NULL)) OR (([t1].[Email] IS NOT NULL) AND ([t2].[Email] IS NOT NULL) AND ([t1].[Email] = [t2].[Email]))) AND (CONVERT(DATE, [t2].[End_DateTime]) = @p0)
GROUP BY [t2].[Chatbot_Name]
) AS [t3]
)) = @p1
GO
在上面的语句之后,为linq查询返回的每条记录附加了另一个select语句。 (> 200次)
-- Region Parameters
DECLARE @p0 DateTime = '2017-06-07 00:00:00.000'
DECLARE @x1 VarChar(1000) = '(CENSORED)'
-- EndRegion
SELECT [t0].[rownames] AS [Rownames], [t0].[Report_ConvNumber], [t0].[Email], [t0].[AD_Num], [t0].[Disp_Name], [t0].[Start_DateTime], [t0].[End_DateTime], [t0].[NumOfMessages], [t0].[Duration], [t0].[Chatbot_Name], [t0].[feedback_score] AS [Feedback_score]
FROM [AI_Conversations] AS [t0]
WHERE (((@x1 IS NULL) AND ([t0].[Email] IS NULL)) OR ((@x1 IS NOT NULL) AND ([t0].[Email] IS NOT NULL) AND (@x1 = [t0].[Email]))) AND (CONVERT(DATE, [t0].[End_DateTime]) = @p0)
GO
我希望返回的SQL查询看起来与此类似
-- Region Parameters
DECLARE @p0 DateTime = DATEADD(dd, -1, cast(Getdate() as date))
DECLARE @p1 Int = 1
-- EndRegion
SELECT [t1].[Email],
[t1].[Disp_Name] AS Name,
[t1].[Report_ConvNumber] AS Reference
FROM (
SELECT [t0].[Email],
[t0].[Disp_Name],
[t0].[Report_ConvNumber]
FROM [AI_Conversations] AS [t0]
WHERE CONVERT(DATE, [t0].[Start_DateTime]) = @p0
GROUP BY [t0].[Email],
[t0].[Disp_Name],
[t0].[Report_ConvNumber]
) AS [t1]
WHERE ((
SELECT COUNT(*)
FROM (
SELECT NULL AS [EMPTY]
FROM [AI_Conversations] AS [t2]
WHERE ((([t1].[Email] IS NULL) AND ([t2].[Email] IS NULL)) OR (([t1].[Email] IS NOT NULL) AND ([t2].[Email] IS NOT NULL) AND ([t1].[Email] = [t2].[Email]))) AND (CONVERT(DATE, [t2].[Start_DateTime]) = @p0)
GROUP BY [t2].[Chatbot_Name]
) AS [t3]
)) = @p1
GO
有人能够告诉我为什么LinqPad会返回这么详细的SQL查询吗? 如何调整LINQ查询以返回简单的' SQL查询就像我提供的期望一样?
如果重要的话,它是使用Linqpad 5的MSSQL 2014服务器
编辑:
在Sgtmoore建议删除.ToList()后,我得到了以下SQL输出,这或多或少符合我的期望。
-- Region Parameters
DECLARE @p0 DateTime = '2017-05-04 00:00:00.000'
DECLARE @p1 Int = 1
-- EndRegion
SELECT (
SELECT [t5].[AD_Num]
FROM (
SELECT TOP (1) [t4].[AD_Num]
FROM [AI_Conversations] AS [t4]
WHERE ((([t1].[Email] IS NULL) AND ([t4].[Email] IS NULL)) OR (([t1].[Email] IS NOT NULL) AND ([t4].[Email] IS NOT NULL) AND ([t1].[Email] = [t4].[Email]))) AND (CONVERT(DATE, [t4].[End_DateTime]) = @p0)
) AS [t5]
) AS [Name], (
SELECT [t7].[Email]
FROM (
SELECT TOP (1) [t6].[Email]
FROM [AI_Conversations] AS [t6]
WHERE ((([t1].[Email] IS NULL) AND ([t6].[Email] IS NULL)) OR (([t1].[Email] IS NOT NULL) AND ([t6].[Email] IS NOT NULL) AND ([t1].[Email] = [t6].[Email]))) AND (CONVERT(DATE, [t6].[End_DateTime]) = @p0)
) AS [t7]
) AS [Email], (
SELECT [t9].[Report_ConvNumber]
FROM (
SELECT TOP (1) [t8].[Report_ConvNumber]
FROM [AI_Conversations] AS [t8]
WHERE ((([t1].[Email] IS NULL) AND ([t8].[Email] IS NULL)) OR (([t1].[Email] IS NOT NULL) AND ([t8].[Email] IS NOT NULL) AND ([t1].[Email] = [t8].[Email]))) AND (CONVERT(DATE, [t8].[End_DateTime]) = @p0)
) AS [t9]
) AS [Reference]
FROM (
SELECT [t0].[Email]
FROM [AI_Conversations] AS [t0]
WHERE CONVERT(DATE, [t0].[End_DateTime]) = @p0
GROUP BY [t0].[Email]
) AS [t1]
WHERE ((
SELECT COUNT(*)
FROM (
SELECT NULL AS [EMPTY]
FROM [AI_Conversations] AS [t2]
WHERE ((([t1].[Email] IS NULL) AND ([t2].[Email] IS NULL)) OR (([t1].[Email] IS NOT NULL) AND ([t2].[Email] IS NOT NULL) AND ([t1].[Email] = [t2].[Email]))) AND (CONVERT(DATE, [t2].[End_DateTime]) = @p0)
GROUP BY [t2].[Chatbot_Name]
) AS [t3]
)) = @p1
答案 0 :(得分:2)
我认为主要问题是中间的.ToList()
是查询。但是,如果删除它,查询将失败,因为Linq2Sql不支持LastOrDefault。
所以我认为您需要使用.FirstOrDefault()
并在必要时撤消排序顺序。
这会产生更简单的TSQL,但仍然不像预期的输出那样。从那看起来,你看起来想要通过电子邮件,参考和Report_ConvNumber进行分组,例如
var result2 = AI_Conversations
.Where(f => f.End_DateTime.Value.Date == DateTime.Now.AddDays(-1).Date)
.GroupBy(f => new {f.Email, f.Reference, f.Report_ConvNumber)
.Where(f => f.GroupBy(z => z.Chatbot_Name).Count() == 1)
.Select(f => new
{
Name = f.Key.Disp_Name,
f.Key.Email,
Reference = f.KeyReport_ConvNumber
});
result2.Dump();