Отображение пользователя, ролей и RolePermissions - PullRequest
0 голосов
/ 19 октября 2011

У меня есть следующие объекты:

User
Role

, а затем таблица соединения:

UsersRoles (UserId, RoleId)

, а затем таблица RolePermissions:

RolePermissions(Id, RoleId, ....)

ИтакСущность пользователя, которую я хочу сделать:

user.Roles
user.RolePermissions

Моя карта пользователя выглядит следующим образом:

public class UserMap : ClassMap<User>
{
   public UserMap()
   {

      HasManyToMany(x => x.Roles)
            .Table("RolesUsers")
            .Access.CamelCaseField(Prefix.Underscore)
            .ParentKeyColumn("UserId")
            .ChildKeyColumn("RoleId")
            .Cascade.All()
            .Inverse();
   }

}

Теперь, когда я создаю нового пользователя, например:

var user = new User { ... };
user.AddRole(new Role { .... } );

UserRepository.Create(user);

Сохраняет пользователя и сохраняет роль, но не вставляет в таблицу RolesUsers?

Также, как добавить свойство, чтобы получить все разрешения RolePermissions дляa Пользователь?

Обновление

Мой ролевая карта имеет:

 HasManyToMany(x => x.Users)
            .Table("RolesUsers")
            .Access.CamelCaseField(Prefix.Underscore)
            .ParentKeyColumn("RoleId")
            .ChildKeyColumn("UserId")
            .Cascade.All();

Мой модульный тест на самом деле проходит, но я думаю, что это потому, чтоЯ не знаю, как очистить кэш 1-го уровня, и он даже не запрашивает базу данных с помощью вызова testUser:

     [Test]
    public void ShouldAddARoleToAUser()
    {
        int userId = -1;
        using (var tx = UserRepository.SessionFactory.OpenSession().BeginTransaction())
        {

            var user = FactoryGirl.GetUser();
            user.AddRole(FactoryGirl.GetRole());

            UserRepository.Create(user);

            tx.Commit();

            UserRepository.SessionFactory.OpenSession().Flush();

            userId = user.Id;
        }

        var testUser = UserRepository.Get(userId);

        Assert.IsNotNull(testUser);
        Assert.IsNotNull(testUser.Roles);
        Assert.IsTrue(testUser.Roles.Count == 1);
        Assert.IsTrue(testUser.Roles[0].Id > 0);

    }

Обновление II

Мой user.cs выглядит так:

        private IList<Role> _roles = new List<Role>(); 

        public virtual IList<Role> Roles
        { 
            get { return _roles;  }
        }

        public virtual void AddRole(Role role)
        {
            if(!_roles.Contains(role))
            {
                _roles.Add(role);
            }
        }

Role.cs:

        private IList<User> _users = new List<User>();
        public virtual IList<User> Users
        {
            get { return _users; }
        }

Обновление III

Странно, это мойтесты пройдены, но, глядя на профилировщик, я вижу, что это даже неХит SQL Server, поэтому, хотя я вызываю Flush, а затем делать Get (userId) он загружает объект из памяти. Кроме того, если взглянуть на другой конец отношения (Role), Role.Users - это {}, так что это проблема?

Ответы [ 3 ]

2 голосов
/ 21 октября 2011

Как предполагает Брук, объявление .Inverse() в отношении отношений является причиной того, что UserRole не сохраняются.

взято из ссылки на Nhibernate (это относится к 3.2, но то же самое существует для более ранних версий на NH) http://nhibernate.info/doc/nh/en/index.html#collections-bidirectional Там прямо сказано:

" Изменения, внесенные только в обратный конец ассоциации, не сохраняются "

И вы меняете обратный конец ассоциации, User.Roles и, конечно же, не сохраняется.

Таким образом, вы либо изменяете декларацию отображения или код, чтобы выполнить сохранение на неинверсном конце ассоциации. Первое решение может (или не может) создать проблему, если у вас есть другой код, который зависит от того, что обратное объявление находится на User.Roles

примечание, вы сказали, что не знаете, чтобы очистить кэш 1-го уровня, соответствующие вызовы:

ISession.Clear() для эффекта steamroller на кеш

ISession.Evict(entity) для определенного объекта

1 голос
/ 19 октября 2011

Если вы используете личные резервные поля для своих коллекций, я думаю, вы должны отобразить их следующим образом:

public class UserMap : ClassMap<User>
{
   public UserMap()
   {
      HasManyToMany(x => x.Roles)
                .Table("RolesUsers")
                .Access.AsCamelCaseField(Prefix.Underscore)
                .ParentKeyColumn("UserId")
                .ChildKeyColumn("RoleId")
                .Cascade.All()
                .Inverse();
   }
}

Разница ключа выше .Access.AsCamelCaseField(Prefix.Underscore)

Edit:

В дополнение к этому, я думаю, вам нужно упростить ваш тест до следующего:

User newUser = new User();
Role newRole = new Role();
newUser.AddRole(newRole);
newRole.AddUser(newUser);

using (NHibernate.ISession session = iSessionFactory.OpenSession())
{
    using (NHibernate.ITransaction tran = session.BeginTransaction())
    {
        session.Save(newUser);
        tran.Commit();
    }
}

Выше может быть неточным, но я думаю, вы понимаете, о чем я говорю.

0 голосов
/ 19 октября 2011

Убедитесь, что вы делаете вставку в транзакции.NHibernate не будет вставлять значения в присоединяющуюся таблицу без него

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