课程以外的课堂作业

时间:2014-09-24 09:14:59

标签: c# fluent-nhibernate

正如您在以下代码中看到的,我在Save方法中关闭会话。我猜这就是为什么AddUserSettings无效的原因。使这项工作的最佳做​​法是什么?在Save方法关闭会话是不是很糟糕?在UserSettings保存时,DB中没有用户,那么是否会产生问题?如何处理会话外的问题?

用户

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;
}

用户设置

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();

2 个答案:

答案 0 :(得分:1)

每个业务操作都应该使用一个会话,因此在每个保存方法中对它进行微观管理并不是一个好主意:

  • 更多往返,因为NHibernate无法一起批量多次插入/更新
  • 无法在多个实体上定义交易!!!
  • 性能太差,因为数据库必须为每次插入/更新创建一个事务(尝试使用“框架”插入10k用户,然后使用一个会话和事务)
  • 必须隐式处理更改跟踪(调用可能会更改实体的方法,并且只有在更改后会话才会更新vs在您的情况下,它将始终更新所有字段,因为它不知道是否/更改了什么)
  • 单元测试更难,因为总有一个全局NHibernateHelper(sessionfactory)
  • 您必须以正确的顺序在您的商务逻辑中创建/保存实体,以避免问题中陈述的问题,因为会为您执行的会话已关闭

有关如何在使用ActiveRecord模式时处理会话,请参阅Caslte.ActiveRecord example。本质上,会话是根据上下文共享的,以实现有意义的事务边界和性能提升。

或者您切换到使用实体之外的会话,以便您拥有更多NHibernate的选项和功能。

答案 1 :(得分: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();