我一直收到以下错误:
无法访问已处置的对象。 对象名称:'AdoTransaction'。
设置遵循http://trason.net/journal/2009/10/7/bootstrapping-nhibernate-with-structuremap.html
中给出的示例这里是IUnitOfWork类(与链接中的类完全相同):
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
CurrentSession = _sessionFactory.OpenSession();
_transaction = CurrentSession.BeginTransaction();
}
public ISession CurrentSession { get; private set; }
public void Dispose()
{
CurrentSession.Close();
CurrentSession = null;
}
public void Commit()
{
_transaction.Commit();
}
}
这里是NHibernateModule(再次完全一样!):
public class NHibernateModule : IHttpModule, IDisposable
{
private IUnitOfWork _unitOfWork;
public void Init(HttpApplication context)
{
context.BeginRequest += ContextBeginRequest;
context.EndRequest += ContextEndRequest;
}
private void ContextBeginRequest(object sender, EventArgs e)
{
_unitOfWork = ObjectFactory.GetInstance<IUnitOfWork>();
}
private void ContextEndRequest(object sender, EventArgs e)
{
Dispose();
}
public void Dispose()
{
if (_unitOfWork == null) return;
_unitOfWork.Commit();
_unitOfWork.Dispose();
}
}
这是我的回购:
public class Repository<T> : IRepository<T>
{
public readonly IUnitOfWork _uow;
public Repository(IUnitOfWork uow)
{
_uow = uow;
}
public Repository()
{
}
#region IRepository<T> Members
public IList<T> GetAll()
{
using (var session = _uow.CurrentSession)
{
return session.CreateCriteria(typeof (T)).List<T>();
}
}
public IList<T> FindAll<T>(IList<Expression<Func<T, bool>>> criteria)
{
var session = _uow.CurrentSession;
var query = from item in session.SessionFactory.OpenSession().Query<T>()
select item;
foreach (var criterion in criteria)
{
query = query.Where(criterion);
}
return query.ToList();
}
public T FindFirst<T>(IList<Expression<Func<T, bool>>> criteria)
{
var col = FindAll(criteria);
if (col.Count > 0)
{
return col.First();
}
else
{
return default(T);
}
}
public T Get(int id)
{
using (var session = _uow.CurrentSession)
{
return session.Get<T>(id);
}
}
public void Save(T entity)
{
using (var session = _uow.CurrentSession)
{
session.Save(entity);
}
}
public void Update(T entity)
{
using (var session = _uow.CurrentSession)
{
session.Update(entity);
session.Flush();
}
}
#endregion
}
}
这是我的引导程序:
public class BootStrapper : IBootstrapper
{
private static bool _hasStarted;
public virtual void BootstrapStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.Scan(s =>
{
s.TheCallingAssembly();
s.AssemblyContainingType<User>();
s.AssemblyContainingType<UserRepository>();
s.AssemblyContainingType<NHibernateRegistry>();
s.LookForRegistries();
});
// Repositories
x.For<WmcStar.Data.IUserRepository>()
.CacheBy(InstanceScope.HttpContext)
.TheDefault.Is.OfConcreteType<UserRepository>();
x.For<IDatabaseBuilder>().TheDefaultIsConcreteType<DatabaseBuilder>();
});
}
public static void Restart()
{
if (_hasStarted)
{
ObjectFactory.ResetDefaults();
}
else
{
Bootstrap();
_hasStarted = true;
}
}
public static void Bootstrap()
{
new BootStrapper().BootstrapStructureMap();
}
}
这是我的NHibernateRegistry:
public class NHibernateRegistry : Registry
{
public NHibernateRegistry()
{
var cfg = new Configuration()
.SetProperty(NHibernate.Cfg.Environment.ReleaseConnections, "on_close")
.SetProperty(NHibernate.Cfg.Environment.Dialect, typeof(NHibernate.Dialect.MsSql2005Dialect).AssemblyQualifiedName)
.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, typeof(NHibernate.Driver.SqlClientDriver).AssemblyQualifiedName)
.SetProperty(NHibernate.Cfg.Environment.ConnectionString, @"my connstring")
.SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, typeof(ProxyFactoryFactory).AssemblyQualifiedName)
.AddAssembly(typeof(User).Assembly);
var sessionFactory = cfg.BuildSessionFactory();
For<Configuration>().Singleton().Use(cfg);
For<ISessionFactory>().Singleton().Use(sessionFactory);
For<ISession>().HybridHttpOrThreadLocalScoped()
.Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped()
.Use<UnitOfWork>();
For<IDatabaseBuilder>().Use<DatabaseBuilder>();
SetAllProperties(x => x.OfType<IUnitOfWork>());
}
}
最后这里是我的global.asax:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
BootStrapper.Bootstrap();
new SchemaExport(ObjectFactory.GetInstance<Configuration>()).Execute(false, true, false);
ObjectFactory.GetInstance<IDatabaseBuilder>().RebuildDatabase();
AutoMapper.Mapper.CreateMap<WmcStar.Model.User, WmcStar.Data.Dto.User>();
}
}
任何人都有任何关于导致这种情况的线索吗?
瓦特://
答案 0 :(得分:4)
使用StructureMap和NHibernate时遇到了这个问题。基本上,我有一个结构图映射一个命名对象(例如,CurrentUser)。在该映射中,它使用NHibernate会话从db中检索当前用户。
然后在我的代码中,我做了类似的事情:
using (var transaction = _session.BeginTransaction())
{
var user = ObjectFactory.GetNamedInstance<User>("CurrentUser");
var myObjects = _session.QueryOver<myObject>().Where(x => x.User == CurrentUser).Future();
transaction.Commit();
}
抛出错误,因为事务是作为当前用户操作的一部分进行处理的。因此,当程序执行到达transaction.Commit()行时,没有要提交的事务。我的解决方案是将用户行移到事务声明之外:
var user = ObjectFactory.GetNamedInstance<User>("CurrentUser");
using (var transaction = _session.BeginTransaction())
{
var myObjects = _session.QueryOver<MyObject>().Where(x => x.User == CurrentUser).Future();
transaction.Commit();
}
这将允许当前用户检索周围的事务独立于MyObject的事务。
答案 1 :(得分:2)
也许它与StructureMap和NHibernate的组合无关,而且与你的代码有什么关系?我猜测没有看到代码,但很可能你处理了一个事务,然后尝试访问它。
答案 2 :(得分:2)
我不知道导致异常的确切问题是什么,但我发现了一些潜在的问题:
输入此列表后,我认为异常是由存储库中的使用块引起的。
如果您想要解释其中一件事,请在评论中问我。
答案 3 :(得分:0)
当我删除对象时,我遇到了相同的错误消息。 在我的情况下,根本原因之一是实体属性值为NULL。 清除空值后,命令执行成功。