使用Linq-to-NHibernate进行多对多查询

时间:2010-05-11 04:01:26

标签: c# fluent-nhibernate many-to-many linq-to-nhibernate

好的家伙(和女孩们),这个人一整晚都让我疯了,我转向你的集体智慧寻求帮助。

我正在使用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
)

为简洁起见,我省略了外键,但基本上归结为:

  • 一个班级可以有很多章节。
  • 一个部门只能属于一个班级,但可以有很多学生。
  • 学生(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的过滤器工作正常,但与学生的多对多关系证明是困难的。每次我尝试运行查询时,都会收到带有消息的ArgumentNullException:

值不能为空。 参数名称:session

我已经考虑过将SectionStudents关系变为Model类的路径,其中包含对Section的引用和对Student的引用,而不是多对多的引用。如果可以的话,我想避免这种情况,我甚至不确定它是否能以这种方式发挥作用。

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

赖安

1 个答案:

答案 0 :(得分:0)

对于任何关心的人,如果Linq-To-NHibernate可以支持子查询(或者我可能完全偏离基础,看起来以下可能会起作用),这可能是Criteria API的限制LINQ到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次查询,但对我来说应该没问题。