CreateAlias ​​и NHibernate объединяют классы без сопоставленных отношений - PullRequest
1 голос
/ 01 марта 2010

Я начинаю задумываться, не слишком ли я глуп, чтобы использовать NHibernate.В настоящее время я использую FluentNHibernate для создания простых отображений БД, и это хорошо сработало для нас.Работая с различными классами изолированно, мы можем читать и писать, выполнять обновления и т. Д. Для всех этих классов.Однако моя проблема заключается в попытке создать запрос, который включает в себя что-то более сложное, чем фильтрация по полям типа сущности.Прекрасный пример проиллюстрирован ниже: *

Соответствующие части сопоставлений:

public class UserMap : ClassMap<User> {
    Id(u => u.Id).Column("UserID").GeneratedBy.Identity();
    //other non-pertinent fields 
}

public class RoleMap : ClassMap<Role> {
    Id(r => r.Id).Column("RoleId").GeneratedByIdentity();
    //snip
}

public class RoleMapMap : ClassMap<RoleMap> {
    Id(rm => rm.Id).Column("RoleMapId").GeneratedByIdentity();
    Map(rm => rm.UserId);
    Map(rm => rm.RoleId);
    //snip
}

Цель состоит в том, чтобы сгенерировать запрос с API Criteria для извлечения всех пользователей определенной роли.- на высоком уровне фильтруйте карту ролей на основе определенного идентификатора роли, затем присоединяйтесь к пользователям и возвращайте только этих пользователей.

Попытка выполнить следующее, но мое использование CreateAlias ​​явно некорректно, так как исключение времени выполнения в основном говорит мне, что он понятия не имеет, что такое "RoleMap" ниже, поскольку он относится к объекту User.

var criteria = session.CreateCriteria<User>().
                CreateAlias("RoleMap", "rm").
                Add(Expression.Eq("rm.UserId", "UserId")).
                Add(Expression.Eq("rm.RoleId", 99)).
                SetResultTransformer(new 
                    DistinctRootEntityResultTransformer());

var users = criteria.List<User>();

Может ли кто-нибудь указать мне правильное направление?Я бы предпочел не редактировать нижележащие объекты для представления коллекций - (например, коллекции User.Roles []), так как есть случаи, когда у нас есть таблицы, которые используются исключительно для объединений, но мы не хотим переходить на средний уровень.Поэтому изучение того, как присоединяться к изолированным классам, будет иметь для нас значение.

1 Ответ

4 голосов
/ 01 марта 2010

В вашем отображении нет способа перейти от пользователя к RoleMap, но это то, что вы пытаетесь сделать в вызове API Criteria. У вас есть несколько вариантов. Вот пара:

1) Разрешить пользователю переходить к RoleMap в вашем отображении. Это самое простое и как обычно это делается.

2) Используйте два запроса, один для получения списка UserIds на основе отношения RoleMap к роли, а затем второй запрос для получения всех пользователей для этих UserIds.

Вы говорите, что не хотите, чтобы коллекция User.Roles находилась на среднем уровне, но NHibernate должен существовать на уровне данных, а не на бизнес-уровне. Вы можете разрешить NHibernate знать о User.Roles, одновременно скрывая его от своего бизнес-уровня.

Присоединение к изолированным классам не совсем то, для чего созданы ORM. ORM созданы для объединения связанных классов. Связанные классы обычно сопоставляются со связанными таблицами на уровне базы данных. Чтобы присоединиться к изолированным классам, вам нужно будет выполнить такие действия, как описанный выше вариант 2, где вы выполняете несколько запросов и / или решаете проблему отсутствия взаимосвязи в пользовательском коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...