Сделайте запрос с одним соединением вместо двух

У меня очень простая схема данных двух таблиц с отношением "многие ко многим":

CREATE TABLE Users
(
 UserId int,
 UserName varchar
)

CREATE TABLE Roles
(
 RoleId int,
 RoleName varchar
)

CREATE TABLE UserRoles
(
 UserId int,
 RoleId int
)

Модель данных и свободное отображение также просты:

class UserEntity
{
  public virtual int Id {get; set;}
  public virtual string Name {get; set;}
  public virtual IList<RoleEntity> Roles {get; set;}
}
class RoleEntity
{
  public virtual int Id {get; set;}
  public virtual string Name {get; set;}
  public virtual IList<UserEntity> Users {get; set;}
}

class UserEntityMap : ClassMap<UserEntity>
{
  public UserEntityMap()
  {
    Table("Users");
    Id(x => x.Id).Column("UserId");
    Map(x => x.Name).Column("UserName");
    HasManyToMany(x => x.Roles)
       .Table("dbo.UserRoles").ParentKeyColumn("UserId").ChildKeyColumn("RoleId");
  }
}
class RoleEntityMap : ClassMap<RoleEntity>
{
  public RoleEntityMap()
  {
    Table("Roles");
    Id(x => x.Id).Column("RoleId");
    Map(x => x.Name).Column("RoleName");
    HasManyToMany(x => x.Users)
       .Table("dbo.UserRoles").ParentKeyColumn("RoleId").ChildKeyColumn("UserId");
  }
}

Мне нравится запрашивать все UserId, которые принадлежат роли с RoleId 15, используя NH Query. Я делаю следующее:

IList<int> list = Session.QueryOver<UserEntity>()
  .Inner.JoinQueryOver<RoleEntity>(u => u.Roles)
  .Where(r => r.Id == 15)
  .Select(u => u.Id)
  .List<int>();

Профилировщик NHibernate показывает, что полученный SQL-запрос:

SELECT this_.UserId as y0_
FROM   dbo.Users this_
       inner join dbo.UserRoles userroles3_
         on this_.UserId = userroles3_.UserId
       inner join dbo.Roles user1_
         on userroles3_.RoleId = user1_.RoleId
WHERE  user1_.RoleId = 15 /* @p0 */

Посоветуйте, пожалуйста, как я могу изменить отображение или запрос, чтобы SQL получал одно соединение, например:

SELECT this_.UserId as y0_
FROM   dbo.Users this_
       inner join dbo.UserRoles userroles3_
         on this_.UserId = userroles3_.UserId
WHERE  userroles3_.RoleId = 15 /* @p0 */

1 ответ

Я нашел этот пост на Stackru, который содержит возможные решения. Решение состоит в том, чтобы добавить сущность для таблицы UserRoles и просто запросить ее, как

IList<int> list = Session.QueryOver<UserRolesEntity>()
  .Where(ur => ur.RoleId == 15)
  .Select(ur => ur.UserId)
  .List<int>();
Другие вопросы по тегам