首页 > 解决方案 > 流利的 Nhibernate 忽略 CurrentSessionContext - 或无法带来当前会话

问题描述

我有以下流畅的 NHibernate 设置:

public class NHibernateHelper : INHibernateHelper
    {
        private readonly string _connectionString;
        private readonly object _lockObject = new object();
        private ISessionFactory _sessionFactory;

        public NHibernateHelper(IConfiguration configuration)
        {
            _connectionString = configuration["ConnectionString"];
        }

        public ISessionFactory SessionFactory
        {
            get
            { if (_sessionFactory == null) 
                    CreateSessionFactory(); 
                return _sessionFactory; 
            }
        }
        private void CreateSessionFactory()
        {
            lock (_lockObject)
            {
                 _sessionFactory = Fluently.Configure()
                .Database(MySQLConfiguration.Standard.ConnectionString(_connectionString).ShowSql())
                .CurrentSessionContext<WebSessionContext>()// this is a webapp
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<BaseEntity>())
                .ExposeConfiguration(
                      cfg =>
                      {
                          cfg.SetProperty("current_session_context_class", "web");
                      }).BuildSessionFactory();
         }
       }
      }

这就是我初始化会话和事务的方式,使用调试器我看到下面的代码按时执行,没有抛出异常:

public class TransactionFilter : IActionFilter
{
    private readonly INHibernateHelper nhibernateHelpe;
    private ITransaction transaction;
    public TransactionFilter(INHibernateHelper nhibernateHelpe)
    {
        this.nhibernateHelpe = nhibernateHelpe;
    }
    public NHibernate.ISession session { get; private set; }
    public void OnActionExecuted(ActionExecutedContext context)
    {
        this.transaction.Commit();
        this.transaction.Dispose();
        this.session.Dispose();
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        this.session = nhibernateHelpe.SessionFactory.OpenSession();
        this.transaction = this.session.BeginTransaction();

    }
}

当我打电话给:

 res = nhibernateHelper.SessionFactory.GetCurrentSession().Load<T>(id);

我得到了例外:

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'NHibernate.Context.ReflectiveHttpContext' threw an exception.
  Source=NHibernate
  StackTrace:
   at NHibernate.Context.ReflectiveHttpContext.get_HttpContextCurrentItems()
   at NHibernate.Context.WebSessionContext.GetMap()
   at NHibernate.Context.MapBasedSessionContext.GetConcreteMap()
   at NHibernate.Context.MapBasedSessionContext.get_Session()
   at NHibernate.Context.CurrentSessionContext.CurrentSession()
   at NHibernate.Impl.SessionFactoryImpl.GetCurrentSession()
   at Lob.Backend.Repository.BaseRepository`1.FindById(Int32 id) in C:\work\projects\ey-server-net\Lob.Backend\Repository\BaseRepository.cs:line 69
   at Lob.Backend.Controllers.ResearchController.Id(Int32 id) in C:\work\projects\ey-server-net\Lob.Backend\Controllers\ResearchController.cs:line 54
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()

Inner Exception 1:
NullReferenceException: Object reference not set to an instance of an object.

标签: fluent-nhibernate

解决方案


WebSessionContext是一个包装器HttpContext.Current。所以它在 AspNet Core 中不受支持,因为没有HttpContext.Current.

如果要使用该模式,则需要实现自己的 ICurrentSessionContext。这是一段可以提供帮助的代码:https ://github.com/nhibernate/nhibernate-core/issues/1632#issuecomment-377704293


推荐阅读