0

好吧,伙计们(和女孩们),这个人整晚都让我发疯,我正在向你们的集体智慧寻求帮助。

我使用 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 而不是多对多。如果可以的话,我想避免这种情况,而且我什至不确定它是否会那样工作。

提前感谢任何可以提供帮助的人。

瑞安

4

1 回答 1

0

对于任何关心的人,如果 Linq-To-NHibernate 可以支持子查询(或者我可能完全脱离基础,这可能是 Linq-To 使用的 Criteria API 的限制,那么看起来以下可能会在未来工作-NHibernate):

var sections = (from s in session.Linq<Section>()
where s.Class.StartDate <= DateTime.UtcNow
&& s.Class.EndDate > DateTime.UtcNow
&& s.Students.First(f => f.UserId == userId) != null
select s);

但是,我目前在运行此查询时在 LINQPad 中收到以下异常:

不能在没有投影的条件上使用子查询。

因此,我暂时将其分为 2 个操作。首先获取学生和相应的部分,然后按课程日期过滤。不幸的是,这会导致对数据库的 2 次查询,但对于我的目的来说应该没问题。

于 2010-05-13T02:34:02.267 回答