NHibernate会话自定义数据
我想做的是在为NHibernate配置的Save、Update、Delete侦听器中使用当前用户id 在我看来,最好的方法是在ISession对象中插入此信息,然后在侦听器中读取此信息。但似乎没有任何地方可以这样做 一种方法是实现接口,但是,我找不到任何可以继承的示例或基类(ISession有太多成员)。一旦我完成了我的实现,我就知道监听器可以进行类型转换并获取用户idNHibernate会话自定义数据,nhibernate,Nhibernate,我想做的是在为NHibernate配置的Save、Update、Delete侦听器中使用当前用户id 在我看来,最好的方法是在ISession对象中插入此信息,然后在侦听器中读取此信息。但似乎没有任何地方可以这样做 一种方法是实现接口,但是,我找不到任何可以继承的示例或基类(ISession有太多成员)。一旦我完成了我的实现,我就知道监听器可以进行类型转换并获取用户id 该应用程序是带有Sql Server 2008的ASPNET MVC2。如果每个线程使用一个会话,则可以将其存储在线程静态字段
该应用程序是带有Sql Server 2008的ASPNET MVC2。如果每个线程使用一个会话,则可以将其存储在线程静态字段中:
[ThreadStatic]
private static int userId;
public static void UserId { get { return userId; } set { userId = value; } }
为了避免线程池将值从一个会话传递到另一个会话,您应该在事务结束时重置该值(例如,在事务提交事件中)
注意:我做这件事非常成功。但我已经用一些服务来包装它。只有一个ThreadStatic字段,其中包含自制的TransactionContext,其中包含会话和我需要的所有其他数据
当您通过自己的方法访问会话时,可以改用SessionContext类。它需要更改呼叫者,但您不必包装会话 大概是这样的:
public class ISessionContext : IDisposable
{
public ISession Session { get; }
public SessionData Data { get; }
}
public ISessionContext CreateSession()
{
return new SessionContext(SessionFactory.OpenSession(), new SessionData(user));
}
如果每个线程使用会话,则可以将其存储在线程静态字段中:
[ThreadStatic]
private static int userId;
public static void UserId { get { return userId; } set { userId = value; } }
为了避免线程池将值从一个会话传递到另一个会话,您应该在事务结束时重置该值(例如,在事务提交事件中)
注意:我做这件事非常成功。但我已经用一些服务来包装它。只有一个ThreadStatic字段,其中包含自制的TransactionContext,其中包含会话和我需要的所有其他数据
当您通过自己的方法访问会话时,可以改用SessionContext类。它需要更改呼叫者,但您不必包装会话 大概是这样的:
public class ISessionContext : IDisposable
{
public ISession Session { get; }
public SessionData Data { get; }
}
public ISessionContext CreateSession()
{
return new SessionContext(SessionFactory.OpenSession(), new SessionData(user));
}
我想我知道的更好 我刚刚创建了一个实现NHibernate.ISession的包装器,因此在我的方法中:
public NHibernate.ISession OpenDataSession(int userId)
{
return new SessionWrapper(SessionFactory.OpenSession(), userId, this);
}
这样,在我的侦听器中,我只需键入cast to SessionWrapper并获取UserId属性
到目前为止,它工作得很好,我的包装器还实现了IDisposable,所以应该可以
如果有人知道得更清楚,请告诉我
更新:根据要求提供更多信息
SessionWrapper类定义:只需实现NHibernate.iseSession并将所有方法重新映射到wrappedSession(构造函数的第一个参数),如下所示:
其思想是,通过使用Ninject,您可以将NHibernate.ISession绑定到此包装器。尽管这假设UserSession对象也可由容器访问,这是一种真实情况,因为UserSession可以存储在会话包中
更新2(随着我的发展:D):我有另一种方法来做,我认为这更好
我所拥有的不是包装器,而是一个接口IUserSessionStore,它基本上只有一个方法:GetUserSession()返回UserSession对象。此接口位于需要此信息的所有类的构造函数中
通过Ninject,我只需将这个接口映射到一个名为UserSessionStore_ASPNETSession的类,该类通过将对象存储到ASPNET会话包中来实现这一点
显然,我假设这是一个所有内容都在一个层中的网站(不涉及远程处理或wcf)
我相信这是更干净,更快地实施,它也有利于所有其他层,可能需要这些信息
谢谢 我想,我想我知道得更好 我刚刚创建了一个实现NHibernate.ISession的包装器,因此在我的方法中:
public NHibernate.ISession OpenDataSession(int userId)
{
return new SessionWrapper(SessionFactory.OpenSession(), userId, this);
}
这样,在我的侦听器中,我只需键入cast to SessionWrapper并获取UserId属性
到目前为止,它工作得很好,我的包装器还实现了IDisposable,所以应该可以
如果有人知道得更清楚,请告诉我
更新:根据要求提供更多信息
SessionWrapper类定义:只需实现NHibernate.iseSession并将所有方法重新映射到wrappedSession(构造函数的第一个参数),如下所示:
其思想是,通过使用Ninject,您可以将NHibernate.ISession绑定到此包装器。尽管这假设UserSession对象也可由容器访问,这是一种真实情况,因为UserSession可以存储在会话包中
更新2(随着我的发展:D):我有另一种方法来做,我认为这更好
我所拥有的不是包装器,而是一个接口IUserSessionStore,它基本上只有一个方法:GetUserSession()返回UserSession对象。此接口位于需要此信息的所有类的构造函数中
通过Ninject,我只需将这个接口映射到一个名为UserSessionStore_ASPNETSession的类,该类通过将对象存储到ASPNET会话包中来实现这一点
显然,我假设这是一个所有内容都在一个层中的网站(不涉及远程处理或wcf)
我相信这是更干净,更快地实施,它也有利于所有其他层,可能需要这些信息
谢谢 我也有同样的问题,但我的情况不同: 我有一个
NHibernateSessionManager
,它处理ISession
,ITransaction
等
然后我在NHibernateSessionManager
中使用CallContext.SetData
保存编辑器实体,然后使用CallContext.GetData
在IPreUpdateEventListener
,IPreInsertEventListener
,IPreDeleteEventListener
CallContext文档:
在web上下文中,我使用了
HttpContext.Current.Items
我有同样的问题,但我的情况不同:
我有一个NHibernateSessionManager
,它处理ISession
,它