当我在我的mvc应用程序中尝试并保存我的“公司”实体时,我收到以下错误
具有相同标识符值的不同对象已经与会话相关联:2,实体:
我正在使用IOC容器
private class EStoreDependencies : NinjectModule { public override void Load() { Bind<ICompanyRepository>().To<CompanyRepository>().WithConstructorArgument("session",NHibernateHelper.OpenSession()); } }
我的公司资料库
public class CompanyRepository : ICompanyRepository { private ISession _session; public CompanyRepository(ISession session) { _session = session; } public void Update(Company company) { using (ITransaction transaction = _session.BeginTransaction()) { _session.Update(company); transaction.Commit(); } }
}
和会话助手
public class NHibernateHelper { private static ISessionFactory _sessionFactory; const string SessionKey = "MySession"; private static ISessionFactory SessionFactory { get { if (_sessionFactory == null) { var configuration = new Configuration(); configuration.Configure(); configuration.AddAssembly(typeof(UserProfile).Assembly); configuration.SetProperty(NHibernate.Cfg.Environment.ConnectionStringName,System.Environment.MachineName); _sessionFactory = configuration.BuildSessionFactory(); } return _sessionFactory; } } public static ISession OpenSession() { var context = HttpContext.Current; //.GetCurrentSession() if (context != null && context.Items.Contains(SessionKey)) { //Return already open ISession return (ISession)context.Items[SessionKey]; } else { //Create new ISession and store in HttpContext var newSession = SessionFactory.OpenSession(); if (context != null) context.Items[SessionKey] = newSession; return newSession; } } }
我的MVC行动
[HttpPost] public ActionResult Edit(EStore.Domain.Model.Company company) { if (company.Id > 0) { _companyRepository.Update(company); _statusResponses.Add(StatusResponseHelper.Create(Constants .RecordUpdated(),StatusResponseLookup.Success)); } else { company.CreatedByUserId = currentUserId; _companyRepository.Add(company); } var viewmodel = Editviewmodel(company.Id,_statusResponses); return View("Edit",viewmodel); }
解决方法
我知道这有点迟了,你可能已经找到了解决方案,但也许其他人可以从中受益
当您更新保存在缓存中的实体的实例时,会从nHibernate引发此错误。基本上,nHibernate在加载缓存后将对象存储在缓存中,因此下一次调用将从缓存中获取。如果更新缓存上存在的实例nHibernate会抛出此错误,否则可能会在加载对象的旧副本时造成脏读和冲突。
要解决这个问题,您需要使用Evict方法从缓存中删除对象,如:
public ActionResult Edit(EStore.Domain.Model.Company company) { if (company.Id > 0) { **ISession.Evict(company);** _companyRepository.Update(company);
希望这可以帮助。