Я работаю над пользовательским расширением linq для nHibernate, расширяя BaseHqlGeneratorForMethod.Техника описана здесь: http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html
Мне удалось реализовать их для различных типов операций, но я должен сказать - преобразование простого выражения linq в его полное дерево выражений не так просто!Я застрял на одном сейчас.
Для этого примера у меня есть три сущности.Employee
, Group
и EmployeeGroup
.Класс EmployeeGroup устанавливает отношение «многие ко многим» между Employee и Group.Я должен специально создать промежуточный класс, потому что есть дополнительные свойства для отслеживания, как и конкретные разрешения, которые каждый сотрудник имеет в каждой группе.Таким образом, существует два отношения «один ко многим», а не отношение «многие ко многим» в nHibernate.
Теперь скажите, что я хочу получить все группы, в которых содержится определенный сотрудник.Я могу написать этот запрос:
var groups = session.Query<Group>()
.Where(g => g.EmployeeGroups.Any(eg => eg.Employee == employee));
Это прекрасно работает, но это много, чтобы напечатать.Я бы предпочел сделать это:
var groups = session.Query<Group>().Where(g => g.HasEmployee(employee));
Я начинаю с создания метода расширения следующим образом:
public static bool HasEmployee(this Group group, Employee employee)
{
return group.EmployeeGroups.Any(eg => eg.Employee == employee);
}
Это работает при запросе локального списка групп, ноне против сессии nHibernate.Для этого я также должен создать расширение linq и зарегистрировать его.Как и в статье (ссылка выше), я создаю класс GroupHasEmployeeGenerator
, который расширяет BaseHqlGeneratorForMethod
.Я установил свойство .SupportedMethods
для ссылки на мой метод расширения HasEmployee.
Там, где я теряюсь, значение переопределения равно BuildHql
.Выражение для построения довольно быстро усложняется.Я полагаю, так как я заменяю предложение .Any
- хорошее место для начала - источник встроенного класса AnyHqlGenerator
.Но это не учитывает, что источник является свойством исходного элемента, и это также не учитывает, что у меня нет лямбда-выражения для представления предложения where.Мне нужно собрать эти детали вручную.
Пока нет смысла публиковать мои попытки, поскольку все они довольно далеки от всего, что будет работать.
Кто-нибудь, пожалуйстапомогите мне преобразовать это простое выражение в подходящий набор методов для переопределения метода BuildHql
?
Если есть какая-либо лучшая документация для этого, пожалуйста, дайте мне знать.Спасибо.