У меня есть сайт, который работает на .Net 3.5 под управлением Nhibernate 2.1.0.4000. Мы используем весну как наш ProxyFactory.
Все отлично работает. Я попытался обновить проект до .Net 4.0 с помощью мастера. Все прошло гладко.
Но как только код пытается что-то сделать с Nhibernate, я получаю очень недружественное исключение System.ExecutionEngineException. Нет трассировки стека и нет внутреннего исключения.
Мы используем класс NhibernateHelper (ниже), и я поэкспериментировал с ним, и сессия настроена нормально (без исключения). Детали не изменились с версии .net 3.5
Первая попытка получить что-то из БД не удалась
Сессия открывается в обработчике в начале запроса (не показано ниже).
Мы также используем единство, которое настраивается при запуске приложения (не уверен, имеет ли это какое-либо отношение)
Первый звонок в Nhibernate -
var emp = NHibernateHelper.CurrentSession.Get<SMS.DomainModel.Employee>(-200694);
Я просто хочу сообщение об ошибке, которое что-то значит и дает мне что-то продолжить.
Я попытался посмотреть на NhibernateProfiler, и все, что зарегистрировано, - это начало сеанса.
Любая помощь очень ценится
Класс NhibernateHelper выглядит следующим образом
using System;
using System.Configuration;
using System.IO;
using System.Reflection;
using FluentNHibernate;
using FluentNHibernate.Cfg;
using HibernatingRhinos.NHibernate.Profiler.Appender;
using log4net;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Event;
using NHibernate.Tool.hbm2ddl;
using SMS.Infrastructure.Persistence.Logging;
using SMS.Infrastructure.Persistence.Mappings;
using Configuration=NHibernate.Cfg.Configuration;
using System.Data.SqlClient;
namespace SMS.Infrastructure.Persistence
{
public static class NHibernateHelper
{
static readonly ILog Log = LogManager.GetLogger(typeof(NHibernateHelper));
static Configuration configuration;
public static ISessionFactory SessionFactory
{
get
{
return Singleton.sessionFactory;
}
}
// Lazy singleton pattern from http://www.yoda.arachsys.com/csharp/singleton.html
class Singleton
{
static Singleton() { }
internal static readonly ISessionFactory sessionFactory = CreateSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
public static ISession CurrentSession
{
get { return SessionFactory.GetCurrentSession(); }
}
static ISessionFactory CreateSessionFactory()
{
try
{
Log.Info("Creating NHibernate session factory");
NHibernateProfiler.Initialize();
configuration = new Configuration();
try
{
// Try to configure NHibernate automagically...
configuration.Configure();
}
catch (HibernateConfigException e)
{
if (e.InnerException is IOException)
{
// Otherwise specify a file name manually.
configuration.Configure("hibernate.cfg.xml");
}
else
throw;
}
Log.Info("Registering custom SMS event listeners");
RegisterCustomListeners(configuration);
// Has someone specified a default_schema? No? try and guess
// it from the (Enterprise Library :/ ) query string.
if (!configuration.Properties.ContainsKey("default_schema"))
{
Log.Info("Setting default schema");
configuration.SetProperty("default_schema", GetDefaultSchema());
}
ISessionFactory sessionFactory = Fluently.Configure(configuration)
.Mappings(m =>
{
m.HbmMappings.AddFromAssemblyOf<BusinessUnitTypeMapping>();
m.FluentMappings.AddFromAssemblyOf<BusinessUnitTypeMapping>();
})
.BuildSessionFactory();
Log.Info("Session factory was configured successfully");
return sessionFactory;
}
catch (Exception ex)
{
throw new ArgumentNullException(ex.ToString());
}
}
/// <summary>
/// NHibernate allows custom event listeners to be registered in
/// config files or programmatically. Due to the re-use of configs in
/// SMS, we chose to do it via code.
///
/// This is how we extend NHibernate for SMS, and this is why
/// NHibernate is the best ORM..!
/// </summary>
static void RegisterCustomListeners(Configuration config)
{
if (config == null)
throw new ArgumentNullException("config");
// Event listeners for audit logging.
//config.SetListener(ListenerType.PreInsert, new AuditEventListener());
//config.SetListener(ListenerType.PreUpdate, new AuditEventListener());
//config.SetListener(ListenerType.PreDelete, new AuditEventListener());
// Event listener for wiring up .NET events between parent/child
// objects, and the intermediary mapping for Tasks.
//
// Warning: be careful with the order in which these listeners are
// added!!!
//
// BindEventsOnLoadListener must come before
// TaskAddresseeLoadEventListener for example otherwise OSM Task
// Decorators don't attach properly.
config.SetListeners(ListenerType.PostLoad, new IPostLoadEventListener[]
{
new BindEventsOnLoadListener(),
new TaskAddresseeLoadEventListener()
});
}
/// <summary>
/// Optional step: destroy and re-create the database scheme based on
/// the mapping files. Gives you a totally clean database in between
/// testing each fixture.
/// </summary>
public static void ExportDatabaseSchema(string fileName)
{
if (configuration == null)
CreateSessionFactory();
Log.InfoFormat("Exporting DDL to {0}", fileName);
var exporter = new SchemaExport(configuration);
exporter.SetOutputFile(fileName);
exporter.Execute(true, false, false);
}
public static void ExportFluentMappings(string directoryName)
{
Log.InfoFormat("Exporting fluent mappings to {0}", directoryName);
var model = new PersistenceModel();
model.AddMappingsFromAssembly(Assembly.GetAssembly(typeof(BusinessUnitTypeMapping)));
model.WriteMappingsTo(directoryName);
}
/// <summary>
/// hibernate's default_schema is worked out programmatically from the
/// Enterprise Library connection string. E.g.
/// Initial Catalog=OSM2Tests --> default_schema = SMS2Tests.dbo
/// </summary>
public static string GetDefaultSchema()
{
try
{
DatabaseSettings settings = DatabaseSettings.GetDatabaseSettings(new SystemConfigurationSource());
var connectionstring = ConfigurationManager.ConnectionStrings[settings.DefaultDatabase].ConnectionString;
var initialCatalog = new SqlConnectionStringBuilder(connectionstring).InitialCatalog;
return String.Format("{0}.dbo", initialCatalog);
}
catch (Exception)
{
throw new Exception("Could not get default schema from connection string.");
}
}
}
}