NHibernate会话自定义数据

NHibernate会话自定义数据,nhibernate,Nhibernate,我想做的是在为NHibernate配置的Save、Update、Delete侦听器中使用当前用户id 在我看来,最好的方法是在ISession对象中插入此信息,然后在侦听器中读取此信息。但似乎没有任何地方可以这样做 一种方法是实现接口,但是,我找不到任何可以继承的示例或基类(ISession有太多成员)。一旦我完成了我的实现,我就知道监听器可以进行类型转换并获取用户id 该应用程序是带有Sql Server 2008的ASPNET MVC2。如果每个线程使用一个会话,则可以将其存储在线程静态字段

我想做的是在为NHibernate配置的Save、Update、Delete侦听器中使用当前用户id

在我看来,最好的方法是在ISession对象中插入此信息,然后在侦听器中读取此信息。但似乎没有任何地方可以这样做

一种方法是实现接口,但是,我找不到任何可以继承的示例或基类(ISession有太多成员)。一旦我完成了我的实现,我就知道监听器可以进行类型转换并获取用户id


该应用程序是带有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