2013-08-28 28 views
1

我有一個編寫LINQ查詢的問題,但SQL查詢是沒有問題的。在下面的例子中,我想找到問題沒有答案,請注意問題和答案可以「重用」。還要注意,具有某個QuestionID的問題一次只能激活一次 - 不能重疊。 SQL代碼來生成例如:LINQ與加入越來越少(在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 

正確答案是四個記錄......這些問題fourtimes中沒有答案,當他們活性。

現在我的問題.. 這是真的可以在LINQ做或我必須做一個存儲過程並返回數據的方式?如果可能的話LINQ看起來如何? (我內心的答案是否定的):(

+0

有什麼問題,我不明白WH ich你認爲你不能在LINQ中寫入的SQL查詢的一部分... –

+0

比較左連接時間的部分越來越少,是否沒有解決方法? –

回答

3

是prossible在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; 
+0

'&&!x.answerhistoryid.HasValue'應該在''from ah in'後面。這是一個檢查,只採取左連接失敗的行。 – xanatos

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 
    ) 
+0

我得到的AnswerHistory不能從問題歷史訪問。我的猜測是,因爲他們連接在一個多對多的關係(QuestionID)任何建議如何糾正?我必須拆分表來創建一個外部表來處理它嗎? –

+0

@JerkerPihl ORM通常會遇到「非簡單」關係的問題,就像這個不是簡單地基於主 - 次關鍵一樣。我從來沒有需要這樣做。 – xanatos

+0

我想你使用LINQ to Entity而不是LINQ to SQL? –