2014-09-24 3 views
0

Как вы видите в следующем коде, я закрываю сеанс в методе Save. Наверное, поэтому AddUserSettings не работает. Какова наилучшая практика для этой работы? Является ли закрытие сессии Save методом плохой идеи? На UserSettings сохранить нет пользователя в БД, но это создает проблему? Как я могу справиться с этим вне сеанса?Работа класса за пределами сеанса

Пользователь

public class User : BaseClass<User> 
{ 
    public virtual int UserId { get; set; } 
    public virtual string UserName { get; set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual string Email { get; set; } 
} 

public virtual void AddUserSettings(UserSettings us) 
{ 
    us.User = this; 
    UserSettings = us; 
} 

UserSettings

public class UserSettings : BaseClass<UserSettings> 
{ 
    public virtual int UserSettingsId { get; set; } 
    public virtual User User { get; set; } 
    public virtual string FacebookId { get; set; } 
    public virtual string FacebookToken { get; set; } 
} 

Сохранить метод

using (var session = NHibernateHelper.OpenSession()) 
{ 
    using (var transaction = session.BeginTransaction()) 
    { 
      session.SaveOrUpdate(x); 

      transaction.Commit(); 
    } 
} 

Код

user = new Entity.User(); 
us = new Entity.UserSettings(); 

us.FacebookId = "foo"; 
us.FacebookToken = "foo"; 
user.AddUserSettings(us); 
us.Save(); 

user.UserName = "foo"; 
user.FirstName = "foo"; 
user.LastName = "foo"; 
user.Email= "foo"; 

user.Save(); 

ответ

0

Я нашел проблему;

Сначала мне нужно создать основной объект и сохранить, тогда я могу добавить подкласс без проблем.

user = new Entity.User(); 
user.UserName = "foo"; 
user.FirstName = "foo"; 
user.LastName = "foo"; 
user.Email= "foo"; 
user.Save(); 

us = new Entity.UserSettings(); 
us.FacebookId = "foo"; 
us.FacebookToken = "foo"; 
user.AddUserSettings(us); 
us.Save(); 
1

Сеанс следует использовать в бизнес-операции, так микро управлять им в каждый метод сохранения не является хорошей идеей:

  • более туда и обратно, так как NHibernate не может партии несколько вставок/обновлений вместе
  • невозможно определить транзакцию более чем одной сущности !!!
  • ужасная производительность, поскольку база данных должна создавать транзакцию для каждой вставки/обновления (попробуйте вставить 10k пользователей с вашей «каркасной», а затем с одним сеансом и транзакцией)
  • changetracking должен обрабатываться неявно (вызов метода, который может изменяться объект и сеанс будут обновляться только в том случае, если он изменился, а в вашем случае он всегда будет обновлять все поля, потому что он не знает, что/что изменилось)
  • модульное тестирование сложнее, потому что всегда существует один глобальный NHibernateHelper (sessionfactory)
  • вам необходимо создать/сохранить объекты в логике вашего бизнеса в правильном порядке, чтобы избежать проблем, указанных в вопросе, потому что сеанс, который сделает это за вас закрыто

См. Caslte.ActiveRecord example о том, как обрабатывать сеансы при использовании шаблона ActiveRecord. По сути, сеанс является общим для каждого контекста, чтобы иметь значимые границы транзакций и прирост производительности.

Или вы переключаетесь на использование сеанса вне сущностей, чтобы у вас было больше возможностей и возможностей NHibernate в вашем распоряжении.

Смежные вопросы