Подтвердить что ты не робот

Поддерживаемые операторы NHibernate.LINQ

Я пытаюсь оценить NHibernate.LINQ 1.0 без фактического написания кода. Айенде признался, что эта версия поддержки LINQ является подпарами по сравнению с EF, но для жизни меня я не могу найти страницу, которая объясняет, что поддерживается и не поддерживается в этой реализации. Например, можно ли использовать Skip и Take? Что я не могу использовать?

4b9b3361

Ответ 1

Вы можете проверить LINQ для NHibernate примеры, чтобы увидеть тесты, выполненные самим Айенде, о том, что реализовано, а что нет этого провайдера.

Некоторые из них обычно поддерживаются:

  • Создание анонимного типа. new { Person = x.Name }
  • Первый(). query.First()
  • FirstOrDefault(). query.FirstOrDefault()
  • Один(). query.Single()
  • SingleOrDefault(). query.SingleOrDefault()
  • Совокупный(). query.Aggregate((x1,x2) => x1)
  • Contains(). query.Where(x => x.Name.Contains("Foo"))
  • StartsWith().
  • EndsWith().
  • подстрока(). where db.Methods.Substring(e.FirstName, 1, 2) == "An"
  • Sub-запросы. query.Where(x => x.Company.Id == 4)
  • Count(). query.Where(x => x.Relatives.Count > 0)
  • Любой(). query.Any()
  • Возьмите(). query.Take(10)
  • Пропустить(). query.Take(10).Skip(4)
  • OrderBy(). orderby x.Name descending
  • Заменить(). AfterMethod = e.FirstName.Replace("An", "Zan"),
  • CHARINDEX(). where db.Methods.CharIndex(e.FirstName, 'A') == 1
  • IndexOf(). where e.FirstName.IndexOf("An") == 1

Проблемные:

  • Группа
  • Соединения

Один из моих собственных примеров:

query = NSession.Session.Linq<Catalog>()
            .Where(acc => acc.Company.Status == "A")
        .Where(acc => acc.Id.StartsWith("12-536"))
        .Where(acc => acc.Id.EndsWith("92") || acc.Id.EndsWith("67"))
        .Take(10).OrderBy(acc => acc.Title);

Если вы производственное приложение использует самую последнюю стабильную версию 2.1.2.4, как я, вы застряли в том, что дает нам поставщик NHibernate.Linq, пока NHibernate 3.0 (trunk) не получит стабильную версию, и мы чувствуем себя в безопасности использовать его в основных приложениях. До тех пор я более чем доволен смесью NHibernate.Linq и HQL.

Ответ 2

Основная проверка того, может ли NHibernate работать с оператором Linq, состоит в том, можно ли сериализовать это дерево выражений оператора, затем десериализовать его в другом процессе и получить правильный ответ. Это означает отсутствие внешних замыканий; лямбда должна работать только с тем, что она создает или задается в качестве параметра.

Linq2NH 1.0, IIRC, также дросселируется при использовании членов класса, которые не отображаются, поэтому, если, например, у вас есть рассчитанное на чтение свойство, такое как специальный взвешенный или скользящий средний, вы должны сопоставить его с БД чтобы ссылаться на нее в лямбда (или воссоздать логику в лямбда). Это связано с тем, что дерево выражений в конечном итоге сводится к SQL (через один из NH-промежуточных элементов, в 2.x это ICriteria, в 3.x это HQL), и если NH не может принять выражение и преобразовать его 1:1 в SQL выражение, которое будет успешно оцениваться, оно просто не будет работать.

Существует один специальный случай: Linq2NH, IIRC, достаточно умен, чтобы превратить выражение IList.Contains() в предложение IN. Список должен быть определен в лямбда (например, new[]{"1","2"}.Contains(m.ID)).

Ответ 3

Сообщение в блоге от Айенде с мая этого года. Многое изменилось. NHiberante. Linq 1.0 linq-провайдер устарел с года примерно из-за нового провайдера linq в NHibernate Trunk. Новый провайдер linq еще не полностью завершен, но уже очень полный и пригодный для использования гораздо больше, чем старый поставщик linq. Вещи, которые не работают с новым провайдером linq, считаются ошибками и будут решены когда-нибудь, когда будут сообщены.

Вы можете использовать пропустить и взять со старым и новым провайдером linq. Текущий список известных проблем можно найти на NHibernate Jira. Другие проблемы неизвестны, и все остальные функции уже поддерживаются.