2010-05-11 1 views
0

Хорошо, ребята (и девочки), этот меня заводил всю ночь, и я обращаюсь к вашей коллективной мудрости за помощью.Много-много запросов с 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 
) 

Я опущена внешние ключи для краткости, но в основном это сводится до:

  • Класс может иметь много секций.
  • Раздел может принадлежать только 1 классу, но может иметь много учеников.
  • Студент (aspnet_Users) может принадлежать многим Разделам.

Я установил соответствующие классы моделей и классы 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); 

Очевидно, 2 выше, с треском провалились, если нет студентов, соответствующих USERID для классы текущей даты между датами начала и окончания ... но я просто хотел попробовать.

Фильтры для Class StartDate и EndDate работают нормально, но отношение «многие ко многим» со Студентами оказывается сложным. Каждый раз, когда я пытаюсь запустить запрос, я получаю сообщение ArgumentNullException с сообщением:

Значение не может быть пустым. Имя параметра: сеанс

Я рассмотрел путь, связанный с отношением SectionStudents к классу Model со ссылкой на раздел и ссылкой на ученика, а не на многих. Я бы хотел избежать этого, если смогу, и я даже не уверен, что это сработает.

Заранее благодарим любого, кто может помочь.

Райан

ответ

0

Для тех, кто заботится, это выглядит следующим образом может работать в будущем, если Linq-To-NHibernate поддерживает подзапросы (или я мог бы быть полностью вне базы, и это может быть ограничение Критерии API, который используется Linq-To-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 при выполнении этого запроса:

Невозможно использовать подзапросы на crite ria без проекции.

Так что пока я разделил это на 2 операции. Сначала получите Student и соответствующие разделы, а затем отфильтруйте это по дате Class. К сожалению, это приводит к 2 запросам к базе данных, но это должно быть хорошо для моих целей.

Смежные вопросы