我有三个表Exam,Test和UserTest。
CREATE TABLE [dbo].[Exam] (
[ExamId] INT IDENTITY (1, 1) NOT NULL,
[SubjectId] INT NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
[Description] NVARCHAR (MAX) NOT NULL,
CONSTRAINT [PK_Exam] PRIMARY KEY CLUSTERED ([ExamId] ASC),
CONSTRAINT [FK_ExamSubject] FOREIGN KEY ([SubjectId]) REFERENCES [dbo].[Subject] ([SubjectId]),
CONSTRAINT [FK_Exam_ExamType] FOREIGN KEY ([ExamTypeId]) REFERENCES [dbo].[ExamType] ([ExamTypeId])
);
CREATE TABLE [dbo].[Test] (
[TestId] INT IDENTITY (1, 1) NOT NULL,
[ExamId] INT NOT NULL,
[Title] NVARCHAR (100) NULL,
[Status] INT NOT NULL,
[CreatedDate] DATETIME NOT NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([TestId] ASC),
CONSTRAINT [FK_TestExam] FOREIGN KEY ([ExamId]) REFERENCES [dbo].[Exam] ([ExamId])
);
CREATE TABLE [dbo].[UserTest] (
[UserTestId] INT IDENTITY (1, 1) NOT NULL,
[UserId] NVARCHAR (128) NOT NULL,
[TestId] INT NOT NULL,
[Result] INT NULL
CONSTRAINT [PK_UserTest] PRIMARY KEY CLUSTERED ([UserTestId] ASC),
CONSTRAINT [FK_UserTestTest] FOREIGN KEY ([TestId]) REFERENCES [dbo].[Test] ([TestId])
);
Run Code Online (Sandbox Code Playgroud)
考试可以进行许多测试,而用户可以尝试多次。
如何使用扩展方法语法编写LINQ语句,使我能够看到UserId == 1的以下内容(我在Where子句中假定UserId == 1):
Exam Test Title UserTestID UserId Result
1 1 1a 1 1 20
1 1 1a 2 1 30
1 1 1a 3 1 40
1 2 1b 4 1 98
1 3 1c 5 1 44
2 4 2a
2 5 2b 6 1 12
Run Code Online (Sandbox Code Playgroud)
或者,如果UserId == 2:
Exam Test Title UserTestID UserId Result
1 1 1a 7 2 27
1 2 1b
1 3 1c 8 2 45
2 4 2a
2 5 2b
Run Code Online (Sandbox Code Playgroud)
或者,如果UserId为null
Exam Test Title UserTestID UserId Result
1 1 1a
1 2 1b
1 3 1c
2 4 2a
2 5 2b
Run Code Online (Sandbox Code Playgroud)
请注意,由于我收到的建议,此问题已作了一些更改。现在有悬赏,我希望我可以接受一个快速的答案。
如果您的Test实体有一个UserTests集合,则可以使用以下查询:
string userId = "1";
var result = context.Tests
.SelectMany(t => t.UserTests
.Where(ut => ut.UserId == userId)
.DefaultIfEmpty()
.Select(ut => new
{
ExamId = t.ExamId,
TestId = t.TestId,
Title = t.Title,
UserTestId = (int?)ut.UserTestId,
UserId = ut.UserId,
Result = ut.Result
}))
.OrderBy(x => x.ExamId)
.ThenBy(x => x.TestId)
.ThenBy(x => x.UserTestId)
.ToList();
Run Code Online (Sandbox Code Playgroud)
使用DefaultIfEmpty()此处可以确保给定LEFT OUTER JOIN始终拥有至少一个UserTest实体(可能是null)Test。UserTest例如,将-之类的不可为null的属性UserTestId强制转换为可int?为null的类型非常重要,否则,您可能会遇到一个例外,即NULL从数据库返回的值不能存储为不可为null的.NET类型。
如果您的实体中没有UserTests集合并且不想要集合,则Test可以使用a GroupJoin作为替代,基本上可以通过以下方式使外部连接两个表TestId:
string userId = "1";
var result = context.Tests
.GroupJoin(context.UserTests.Where(ut => ut.UserId == userId),
t => t.TestId,
ut => ut.TestId,
(t, utCollection) => new
{
Test = t,
UserTests = utCollection
})
.SelectMany(x => x.UserTests
.DefaultIfEmpty()
.Select(ut => new
{
ExamId = x.Test.ExamId,
TestId = x.Test.TestId,
Title = x.Test.Title,
UserTestId = (int?)ut.UserTestId,
UserId = ut.UserId,
Result = ut.Result
}))
.OrderBy(x => x.ExamId)
.ThenBy(x => x.TestId)
.ThenBy(x => x.UserTestId)
.ToList();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2971 次 |
| 最近记录: |