C# 在Nhibernate中设置CRUD方法和SessionFactory的好方法是什么?
我目前有一个NHibernateHelper类,它创建了一个会话工厂。我不断收到“会话已关闭”的错误消息。我是不是走错了路?当我调用Add(Login-Login)时会发生错误,Add(User)之后会调用Add(Login-Login) 这是我的存储库:C# 在Nhibernate中设置CRUD方法和SessionFactory的好方法是什么?,c#,nhibernate,sessionfactory,C#,Nhibernate,Sessionfactory,我目前有一个NHibernateHelper类,它创建了一个会话工厂。我不断收到“会话已关闭”的错误消息。我是不是走错了路?当我调用Add(Login-Login)时会发生错误,Add(User)之后会调用Add(Login-Login) 这是我的存储库: internal class UserRepository : IUserRepository { private ISession _db = NHibernateHelper.OpenSession(); public
internal class UserRepository : IUserRepository
{
private ISession _db = NHibernateHelper.OpenSession();
public void Add(User user)
{
using (_db)
{
using (ITransaction transaction = _db.BeginTransaction())
{
IEnumerable<UserRole> userRoles = user.UserRoles;
user.UserRoles = null;
_db.Save(user);
foreach (UserRole userRole in userRoles)
{
userRole.UserID = user.UserID;
_db.Save(userRole);
}
transaction.Commit();
}
}
}
public void Add(Login login)
{
using (_db)
{
using (ITransaction transaction = _db.BeginTransaction())
{
_db.Save(login);
transaction.Commit();
}
}
}
}
内部类UserRepository:IUserRepository
{
私有ISession _db=NHibernateHelper.OpenSession();
公共无效添加(用户)
{
使用(_db)
{
使用(ITransaction事务=_db.BeginTransaction())
{
IEnumerable userRoles=user.userRoles;
user.UserRoles=null;
_db.Save(用户);
foreach(UserRole中的UserRole)
{
userRole.UserID=user.UserID;
_db.Save(用户角色);
}
Commit();
}
}
}
公共作废添加(登录)
{
使用(_db)
{
使用(ITransaction事务=_db.BeginTransaction())
{
_db.Save(登录);
Commit();
}
}
}
}
这是因为您正在使用(\u db)调用,这将在块的末尾关闭会话
与其使用变量_db,不如为每个操作调用OpenSession
public void Add(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
IEnumerable<UserRole> userRoles = user.UserRoles;
user.UserRoles = null;
session.Save(user);
foreach (UserRole userRole in userRoles)
{
userRole.UserID = user.UserID;
session.Save(userRole);
}
transaction.Commit();
}
}
}
工厂的创建成本很高,因此您的助手是一件值得使用的好东西。打开会话是一个廉价的操作,因此不需要像这样的共享会话
下面是指向另一个SO问题的链接,该问题显示了如何使factory helper线程安全:
像上面那样使用它,这不会为每个crud操作创建工厂实例吗?不,工厂是静态单例。将为每个操作创建ISession。有关关闭_db的原因,请参阅我的编辑。-我的答案的第一行。另外,您可以通过在以下行上放置断点来测试是否创建了新工厂:如果(_sessionFactory==null),则每个相关活动组只需要一个事务。如果您正在执行多个更改,请在调用OpenSession后立即创建事务,就像您在问题的第一个代码块中所做的那样,然后在结束大括号之前提交,就像您所做的那样。当我有机会(即回家时),我将制作一个示例应用程序。给我发一封电子邮件,我们可以离线设置一个对话框,也许以后可以将结果作为新答案发布在这里。
public void Add(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
IEnumerable<UserRole> userRoles = user.UserRoles;
user.UserRoles = null;
session.Save(user);
foreach (UserRole userRole in userRoles)
{
userRole.UserID = user.UserID;
session.Save(userRole);
}
transaction.Commit();
}
}
}
public void Add(Login login)
{
using (ISession session = NHibernateHelper.OpenSession())
{
Add(login, session);
}
}
public void Add(Login login, ISession session)
{
//no longer need to create a session here - it is passed in
//using (ISession session = NHibernateHelper.OpenSession())
...Add using the session
}