好吧,伙计们(和女孩们),这个人整晚都让我发疯,我正在向你们的集体智慧寻求帮助。
我使用 Fluent Nhibernate 和 Linq-To-NHibernate 作为我的数据访问故事,并且我有以下简化的数据库结构:
CREATE TABLE [dbo].[Classes](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[EndDate] [datetime2](7) NOT NULL,
CONSTRAINT [PK_Classes] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
CREATE TABLE [dbo].[Sections](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[ClassId] [bigint] NOT NULL,
[InternalCode] [varchar](10) NOT NULL,
CONSTRAINT [PK_Sections] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
CREATE TABLE [dbo].[SectionStudents](
[SectionId] [bigint] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_SectionStudents] PRIMARY KEY CLUSTERED
(
[SectionId] ASC,
[UserId] ASC
)
CREATE TABLE [dbo].[aspnet_Users](
[ApplicationId] [uniqueidentifier] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL,
[UserName] [nvarchar](256) NOT NULL,
[LoweredUserName] [nvarchar](256) NOT NULL,
[MobileAlias] [nvarchar](16) NULL,
[IsAnonymous] [bit] NOT NULL,
[LastActivityDate] [datetime] NOT NULL,
PRIMARY KEY NONCLUSTERED
(
[UserId] ASC
)
为简洁起见,我省略了外键,但本质上归结为:
- 一个类可以有很多节。
- 一个部分只能属于 1 个班级,但可以有许多学生。
- 一个学生 (aspnet_Users) 可以属于多个部分。
我已经设置了相应的 Model 类和 Fluent NHibernate Mapping 类,一切正常。
这就是我卡住的地方。我需要编写一个查询,该查询将根据学生的 UserId 和课程日期返回学生注册的部分。
这是我到目前为止所尝试的:
1.
var sections = (from s in this.Session.Linq<Sections>()
where s.Class.StartDate <= DateTime.UtcNow
&& s.Class.EndDate > DateTime.UtcNow
&& s.Students.First(f => f.UserId == userId) != null
select s);
2.
var sections = (from s in this.Session.Linq<Sections>()
where s.Class.StartDate <= DateTime.UtcNow
&& s.Class.EndDate > DateTime.UtcNow
&& s.Students.Where(w => w.UserId == userId).FirstOrDefault().Id == userId
select s);
显然,如果没有学生匹配 userId 的学生在开始日期和结束日期之间的当前日期,那么上面的 2 将会失败......但我只是想尝试一下。
Class StartDate 和 EndDate 的过滤器工作正常,但事实证明与 Student 的多对多关系很困难。每次我尝试运行查询时,都会收到带有以下消息的 ArgumentNullException:
值不能为空。参数名称:会话
我考虑过让 SectionStudents 关系成为一个 Model 类,并引用 Section 和 Student 而不是多对多。如果可以的话,我想避免这种情况,而且我什至不确定它是否会那样工作。
提前感谢任何可以提供帮助的人。
瑞安