1

我在编写 LINQ 查询时遇到问题,但 SQL 查询没问题。在下面的示例中,我想找到没有答案的问题,请注意问题和答案可以“重复使用”。另请注意,具有特定 QuestionID 的问题一次只能激活一次 - 没有重叠时间。生成示例的 SQL 代码:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[QuestionHistory](
    [QuestionHistoryID] [int] IDENTITY(1,1) NOT NULL,
    [QuestionID] [int] NOT NULL,
    [Question] [nvarchar](100) NOT NULL,
    [AskedTime] [datetime] NOT NULL,
    [LatestResponseTime] [datetime] NOT NULL,
    [UserId] [int] NOT NULL,
 CONSTRAINT [PK_QuestionHistory] PRIMARY KEY CLUSTERED 
(
    [QuestionHistoryID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,        
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[QuestionHistory] ON
INSERT [dbo].[QuestionHistory] ([QuestionHistoryID], [QuestionID], [Question],    
[AskedTime], [LatestResponseTime], [UserId]) VALUES (2, 1, N'A',
CAST(0x0000A20900000000 AS DateTime), CAST(0x0000A20A00000000 AS DateTime), 1)
INSERT [dbo].[QuestionHistory] ([QuestionHistoryID], [QuestionID], [Question],
[AskedTime], [LatestResponseTime], [UserId]) VALUES (3, 1, N'A',
CAST(0x0000A20B00000000 AS DateTime), CAST(0x0000A20E00000000 AS DateTime), 1)
INSERT [dbo].[QuestionHistory] ([QuestionHistoryID], [QuestionID], [Question],
[AskedTime], [LatestResponseTime], [UserId]) VALUES (4, 1, N'A',
CAST(0x0000A1F200000000 AS DateTime), CAST(0x0000A21200000000 AS DateTime), 1)
INSERT [dbo].[QuestionHistory] ([QuestionHistoryID], [QuestionID], [Question],
[AskedTime], [LatestResponseTime], [UserId]) VALUES (5, 2, N'B',
CAST(0x0000A20B00000000 AS DateTime), CAST(0x0000A21100000000 AS DateTime), 1)
INSERT [dbo].[QuestionHistory] ([QuestionHistoryID], [QuestionID], [Question],
[AskedTime], [LatestResponseTime], [UserId]) VALUES (6, 2, N'B',
CAST(0x0000A21400000000 AS DateTime), CAST(0x0000A21E00000000 AS DateTime), 1)
INSERT [dbo].[QuestionHistory] ([QuestionHistoryID], [QuestionID], [Question],
[AskedTime], [LatestResponseTime], [UserId]) VALUES (7, 3, N'C',
CAST(0x0000A21500000000 AS DateTime), CAST(0x0000A21600000000 AS DateTime), 1)
SET IDENTITY_INSERT [dbo].[QuestionHistory] OFF
/****** Object:  Table [dbo].[AnswerHistory]    Script Date: 08/28/2013 09:49:26
 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AnswerHistory](
    [AnswerHistoryID] [int] IDENTITY(1,1) NOT NULL,
    [AnswerID] [int] NOT NULL,
    [QuestionID] [int] NOT NULL,
    [Answer] [nvarchar](50) NOT NULL,
    [ResponseTime] [datetime] NOT NULL,
    [UserId] [int] NOT NULL,

CONSTRAINT [PK_AnswerHistory] PRIMARY KEY CLUSTERED 
(
[AnswerHistoryID] ASC

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,    
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[AnswerHistory] ON
INSERT [dbo].[AnswerHistory] ([AnswerHistoryID], [AnswerID], [QuestionID], [Answer],
[ResponseTime], [UserId]) VALUES (1, 1, 1, N'AA', CAST(0x0000A20D00000000 AS DateTime),
 2)
INSERT [dbo].[AnswerHistory] ([AnswerHistoryID], [AnswerID], [QuestionID], [Answer],
 [ResponseTime], [UserId]) VALUES (2, 1, 1, N'AA', CAST(0x0000A21200000000 AS     DateTime), 2)
INSERT [dbo].[AnswerHistory] ([AnswerHistoryID], [AnswerID], [QuestionID], [Answer], [ResponseTime], [UserId]) VALUES (4, 2, 2, N'AB', CAST(0x0000A21000000000 AS DateTime), 2)
INSERT [dbo].[AnswerHistory] ([AnswerHistoryID], [AnswerID], [QuestionID], [Answer], [ResponseTime], [UserId]) VALUES (5, 3, 2, N'AB', CAST(0x0000A21000000000 AS DateTime), 3)
SET IDENTITY_INSERT [dbo].[AnswerHistory] OFF

生成正确答案的 sql 语句如下:

SELECT * FROM [example].[dbo].[QuestionHistory] qh 
LEFT JOIN  [example].[dbo].[AnswerHistory] ah 
ON qh.questionID=ah.questionID 
AND ah.[ResponseTime]<qh.LatestResponseTime 
AND ah.[responseTime]>qh.AskedTime 
WHERE ah.answerhistoryid IS NULL

正确答案是四条记录……这些问题在活动的时候四次都没有答案。

现在我的问题..这真的可以在 LINQ 中完成,还是我必须执行存储过程并以这种方式返回数据?如果可能的话,LINQ 会是什么样子?(我的直觉答案是否定的):(

4

2 回答 2

3

在 LINQ 中可以这样做:

   var query= from qh in db.QuestionHistory
              join ah in db.AnswerHistory
                           .Where(x=> x.ResponseTime < qh.LatestResponseTime 
                                   && x.responseTime > qh.AskedTime
                                   && !x.answerhistoryid.HasValue) 
              on qh.questionID equals ah.questionID into leftGroup
              from ah in leftGroup.DefaultIfEmpty()
              select qh;
于 2013-08-28T08:20:47.440 回答
0

如果您在 EntityFramework 中定义了 QuestionHistory-AnswerHistory 关系,它应该是这样的:

var query= from qh in db.QuestionHistory
           where !qh.AnswerHistory.Any(x => 
                 x.ResponseTime < qh.LatestResponseTime && 
                 x.responseTime > qh.AskedTime)
           select qh

相当于:

SELECT * 
    FROM [example].[dbo].[QuestionHistory] qh 
    WHERE NOT EXIST (
        SELECT 1 FROM [example].[dbo].[AnswerHistory] ah 
            WHERE qh.questionID=ah.questionID AND 
                  ah.[ResponseTime]<qh.LatestResponseTime AND 
                  ah.[responseTime]>qh.AskedTime
    )
于 2013-08-28T09:29:42.053 回答