如何使 NHibernate 5.2.7 在 ASP.NET Core 3.1 中没有运行时异常?
How to make NHibernate 5.2.7 not have runtime exceptions with ASP.NET Core 3.1?
在我和我的团队正在进行的一个新项目中,我正在探索 NHibernate 5.2.7 / FluentNHibernate 2.1.2 是否与 ASP.NET Core 3.1 兼容。我做了 some research on NHibernate 5.2.3, a slightly earlier version,并且在那个 SO 线程中,他们指出此时的 NHibernate 应该与 .NET Core 兼容。
话虽这么说,但情况似乎并非如此。
下面是我们如何使用NHibernate。我们使用这个 DataContext
对象创建会话(当然是在 using
块中,因为 ISessions
是 IDisposable
!),然后使用 QueryOver 获取或设置数据到我们的数据库.
然而,当我们尝试任何数据库操作时,我们在 _sessionFactory.OpenSession()
调用中得到以下异常:
Could not load type 'System.Runtime.Remoting.Messaging.CallContext' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Inner exception: null
Stack trace: at NHibernate.Impl.SessionIdLoggingContext.get_SessionId()
at NHibernate.Impl.SessionIdLoggingContext..ctor(Guid id)
at NHibernate.Impl.AbstractSessionImpl.BeginContext()
at NHibernate.Impl.AbstractSessionImpl..ctor(ISessionFactoryImplementor factory, ISessionCreationOptions options)
at NHibernate.Impl.SessionImpl..ctor(SessionFactoryImpl factory, ISessionCreationOptions options)
at NHibernate.Impl.SessionFactoryImpl.SessionBuilderImpl`1.OpenSession()
at NHibernate.Impl.SessionFactoryImpl.OpenSession()
at MyRadProject.Core.DataContext.GetSession() in C:\MyRadProject.Core\DataContext.cs:line 18
at MyRadProject.Core.Repositories.UserRepository.GetUsers(Boolean includeInactive) in C:\MyRadProject.Core\Repositories\UserRepository.cs:line 23
at MyRadProject.Web.Controllers.CommonController.GetUsers() in C:\MyRadProject.Web\Controllers\CommonController.cs:line 21
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>g__Logged|12_1>d.MoveNext()
据我的团队所知,此异常 之前 发生在较早版本的 .NET Core 中,原因是未提供某些命名空间或 类在 .NET Core 中(例如 System.Configuration.ConfigurationManager
)由于 .NET Core 和 NHibernate 的共同功劳,这些问题似乎得到了很大缓解。
我仔细检查了我们的数据访问代码存在于 ("MyAwesomeProject.Core") 中的库项目中是否引用了 mscorlib
。在Visual Studio 2019年,我没有看到这样的引用;当我尝试手动引用 mscorlib
时,我收到一条消息 "mscorlib is automatically referenced by the build process."
所有这些引出了我的 问题:
假设上面的 SO 线程在声明 NHibernate 5.1.1+ 与 .NET Core 兼容方面是准确的,我还需要做些什么才能使 NHibernate 5.2.7 不生成运行时异常当我尝试任何数据库操作时?
DataContext.cs
public class DataContext
{
private static ISessionFactory _sessionFactory;
private static bool _startupComplete;
private static readonly object _locker = new object();
public static ISession GetSession()
{
EnsureStartup();
ISession session = _sessionFactory.OpenSession(); // EXCEPTION occurs here!
session.BeginTransaction();
return session;
}
public static void EnsureStartup()
{
if (!_startupComplete)
{
lock (_locker)
{
if (!_startupComplete)
{
PerformStartup();
_startupComplete = true;
}
}
}
}
private static void PerformStartup()
{
InitializeSessionFactory();
}
private static void InitializeSessionFactory()
{
Configuration configuration = BuildConfiguration();
_sessionFactory = configuration.BuildSessionFactory();
}
public static Configuration BuildConfiguration()
{
var configuration = new Configuration().Configure();
return Fluently.Configure(configuration)
.Mappings(cfg => cfg.FluentMappings.AddFromAssembly(typeof(DataContext).Assembly))
.BuildConfiguration();
}
// There are other methods below this point that aren't pertinent to the question.
}
您似乎正在使用库的完整 .NET Framework 版本,因为 CallContext
class 未在 .NET Core/.NET Standard 版本的 NHibernate 中使用(AsyncLocal
是改为使用):
https://github.com/nhibernate/nhibernate-core/blob/c0f50429722b4e061a0c6b40b720db17d33fc85e/src/NHibernate/Impl/SessionIdLoggingContext.cs#L60-L65
因此,要解决您的问题,请尝试使用库的 .NET Core 或 .NET Standard 版本。
在我和我的团队正在进行的一个新项目中,我正在探索 NHibernate 5.2.7 / FluentNHibernate 2.1.2 是否与 ASP.NET Core 3.1 兼容。我做了 some research on NHibernate 5.2.3, a slightly earlier version,并且在那个 SO 线程中,他们指出此时的 NHibernate 应该与 .NET Core 兼容。
话虽这么说,但情况似乎并非如此。
下面是我们如何使用NHibernate。我们使用这个 DataContext
对象创建会话(当然是在 using
块中,因为 ISessions
是 IDisposable
!),然后使用 QueryOver 获取或设置数据到我们的数据库.
然而,当我们尝试任何数据库操作时,我们在 _sessionFactory.OpenSession()
调用中得到以下异常:
Could not load type 'System.Runtime.Remoting.Messaging.CallContext' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Inner exception: null
Stack trace: at NHibernate.Impl.SessionIdLoggingContext.get_SessionId()
at NHibernate.Impl.SessionIdLoggingContext..ctor(Guid id)
at NHibernate.Impl.AbstractSessionImpl.BeginContext()
at NHibernate.Impl.AbstractSessionImpl..ctor(ISessionFactoryImplementor factory, ISessionCreationOptions options)
at NHibernate.Impl.SessionImpl..ctor(SessionFactoryImpl factory, ISessionCreationOptions options)
at NHibernate.Impl.SessionFactoryImpl.SessionBuilderImpl`1.OpenSession()
at NHibernate.Impl.SessionFactoryImpl.OpenSession()
at MyRadProject.Core.DataContext.GetSession() in C:\MyRadProject.Core\DataContext.cs:line 18
at MyRadProject.Core.Repositories.UserRepository.GetUsers(Boolean includeInactive) in C:\MyRadProject.Core\Repositories\UserRepository.cs:line 23
at MyRadProject.Web.Controllers.CommonController.GetUsers() in C:\MyRadProject.Web\Controllers\CommonController.cs:line 21
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>g__Logged|12_1>d.MoveNext()
据我的团队所知,此异常 之前 发生在较早版本的 .NET Core 中,原因是未提供某些命名空间或 类在 .NET Core 中(例如 System.Configuration.ConfigurationManager
)由于 .NET Core 和 NHibernate 的共同功劳,这些问题似乎得到了很大缓解。
我仔细检查了我们的数据访问代码存在于 ("MyAwesomeProject.Core") 中的库项目中是否引用了 mscorlib
。在Visual Studio 2019年,我没有看到这样的引用;当我尝试手动引用 mscorlib
时,我收到一条消息 "mscorlib is automatically referenced by the build process."
所有这些引出了我的 问题:
假设上面的 SO 线程在声明 NHibernate 5.1.1+ 与 .NET Core 兼容方面是准确的,我还需要做些什么才能使 NHibernate 5.2.7 不生成运行时异常当我尝试任何数据库操作时?
DataContext.cs
public class DataContext
{
private static ISessionFactory _sessionFactory;
private static bool _startupComplete;
private static readonly object _locker = new object();
public static ISession GetSession()
{
EnsureStartup();
ISession session = _sessionFactory.OpenSession(); // EXCEPTION occurs here!
session.BeginTransaction();
return session;
}
public static void EnsureStartup()
{
if (!_startupComplete)
{
lock (_locker)
{
if (!_startupComplete)
{
PerformStartup();
_startupComplete = true;
}
}
}
}
private static void PerformStartup()
{
InitializeSessionFactory();
}
private static void InitializeSessionFactory()
{
Configuration configuration = BuildConfiguration();
_sessionFactory = configuration.BuildSessionFactory();
}
public static Configuration BuildConfiguration()
{
var configuration = new Configuration().Configure();
return Fluently.Configure(configuration)
.Mappings(cfg => cfg.FluentMappings.AddFromAssembly(typeof(DataContext).Assembly))
.BuildConfiguration();
}
// There are other methods below this point that aren't pertinent to the question.
}
您似乎正在使用库的完整 .NET Framework 版本,因为 CallContext
class 未在 .NET Core/.NET Standard 版本的 NHibernate 中使用(AsyncLocal
是改为使用):
https://github.com/nhibernate/nhibernate-core/blob/c0f50429722b4e061a0c6b40b720db17d33fc85e/src/NHibernate/Impl/SessionIdLoggingContext.cs#L60-L65
因此,要解决您的问题,请尝试使用库的 .NET Core 或 .NET Standard 版本。