주어진 사용자가 스크립트 질문에 대한 답변을 저장하는 디자인이 있습니다. 하나의 스크립트에는 많은 질문이있을 수 있으며 각 질문에는 주어진 사용자가 여러 번 대답 할 수 있습니다.이 Linq를 더 EF로 만들 수 있습니까?
는 MS SQL 테이블은 더 많거나 적은처럼 (추가 세부 사항을 제거) 볼 :
-Scripts
ScriptId int (PK, identity)
-ScriptQuestions
ScriptId int (PK)
QuestionId int (PK)
-Questions
QuestionId int (PK, identity)
QuestionText varchar
-Answers
AnswerId int (PK, identity)
QuestionId int
UserId int
AnswerText varchar
내가 제공하는 모든 질문과 마지막 답을 주어진 스크립트와 특정 사용자를 위해이 데이터베이스를 쿼리하고 얻을 싶습니다 각 질문마다 (있는 경우). 는 T-SQL에서 나는 이런 식으로 뭔가 할 것 :
SELECT
sq.QuestionId,
q.QuestionText,
la.AnswerText
FROM
ScriptQuestions sq
ON s.ScriptId = sq.ScriptId
INNER JOIN Questions q
ON sq.QuestionId = q.QuestionId
LEFT OUTER JOIN (
SELECT
QuestionId,
AnswerText
FROM Answers
WHERE AnswerId IN (
SELECT
MAX(AnswerId) LastAnswerId
FROM Answers
WHERE UserId = @userId
GROUP BY QuestionId
)
) la
ON q.QuestionId = la.QuestionId
WHERE
sq.ScriptId = @scriptId
(테스트되지 않은,하지만 나는 내가 무엇을 할 것이라고 가까운 생각) 내가 MVC 3 응용 프로그램에 LinqToEF을 사용하고
하고 얻을 그 결과는 내가 사용 :
var questions = from sq in script.ScriptQuestions
select new QuestionsAnswers
{
QuestionId = sq.QuestionId,
QuestionText = sq.Question.QuestionText,
LastAnswer = sq.Question.Answers
.Where(a => a.UserId == userId)
.OrderByDescending(a => a.AnswerId)
.Select(a => a.AnswerText)
.FirstOrDefault()
};
그리고 같은 결과를 얻는다하지만 내가 VS 2010에서 Intellitrace 프로파일 러를 실행하면 그 LINQ는 다음 다른 스크립트와의 모든 질문에 대한 SELECT
문을 보내기에이 변환 볼 수 있습니다 SELECT
statem 모든 대답에 대한 ent. 따라서 스크립트에 20 개의 질문이있는 경우 위와 같이 SQL 문 하나만 보내는 대신 데이터베이스를 적어도 40 번 쿼리합니다.
LinqToEF 문을 작성하는 방법을 변경하려고 시도했지만 n SELECT
문을 극복하지 못했습니다.
올바른 방법 일 수 없습니까? 그렇습니까?
나는이 쿼리를 함께 결합하는 편이 낫다고 생각한다. '스크립트의 sq에서 .Sqriptquestions는 스크립트에 참여합니다. a.questionid의 답변은 sq.questionid와 같습니다. 여기서 userId == a.UserId select new .. {}'. (정확하게는 아니지만 아이디어). Linq는 여분의 내부 쿼리없이 필터링합니다 (실제로 scriptQuestions에서 항목 당 한 번 실행됩니다). – Independent