Сложные запросы в linq to nhibernate - PullRequest
0 голосов
/ 30 августа 2009

Мы используем шаблон подотчетности для организационной структуры. Я использую linq для nhibernate, чтобы найти некоторые отделы и должности, но у меня есть две проблемы.

var query = 
  Repository<Party>.Find(p => p.IsInternal == true)
    .Where(p => p.Parents.Any(c => c.Parent.PartyId == id))
    .Where(p => 
      (
        p.PartyType.PartyTypeId == (int)PartyTypeDbId.Department && 
        _secretariat.Departments.Select(c => c.PartyId).Contains(p.PartyId)
      )
      || 
      (
        p.PartyType.PartyTypeId == (int)PartyTypeDbId.Position && 
        p.Children.Any(c => 
          c.AccountabilityType.AccountabilityTypeId == (int)AccountabilityTypeDbId.TenurePersonOfPosition &&  
          ((Person)c.Child).UserName != null)
        )
    );

Во-первых: я получил «Необработанный тип выражения: 1003» для этой части запроса: «_secretariat.Departments.Select (c => c.PartyId) .Contains (p.PartyId)» и я получил свойство не найдено 'UserName'

У нас много сложных запросов, я думаю, нам нужно использовать хранимую процедуру.

Простите за плохой инглиш!

Ответы [ 3 ]

2 голосов
/ 30 августа 2009

Одна приятная вещь, которую вы можете сделать с помощью LINQ, - разбить ваши запросы на несколько частей. Поскольку вы строите дерево выражений, которое не будет выполнено до тех пор, пока не будут перечислены результаты, вам не нужно делать все это в одной строке (например, SQL).

Вы даже можете создать несколько «повторно используемых» «фильтров», которые вы можете применить к IQueryable. Эти функции фильтра принимают IQueryable в качестве аргумента и возвращают его в качестве результата. Вы можете создать их как методы расширения, если хотите (мне нравится).

Что касается вашей непосредственной проблемы, вы можете попробовать присоединиться к _secretariat вместо попытки подзапроса. Я видел, как они работают в сценариях, где подзапросы не работают.

0 голосов
/ 18 мая 2011

Я только что узнал, что существуют проблемы с Contains при содержании любых методов linq. Тем не менее, Any, кажется, хорошо работает внутри Any, следовательно:

_secretariat.Departments.Select(c => c.PartyId).Any(x => x == p.PartyId)
0 голосов
/ 30 августа 2009

В дополнение к комментариям Ланса вы можете посмотреть на скомпилированный запрос Linq и разделить некоторые обязанности в соответствии с принципами SOLID.

...