我有一个MVC5应用程序,并将hibernate设置成这样:
public class PersistenceInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
//Nhibernate session factory
Component.For<ISessionFactory>().UsingFactoryMethod(CreateNhSessionFactory).LifeStyle.Singleton,
Component.For<ISession>().UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession()).LifestylePerWebRequest(),
//All repoistories
Classes.FromAssembly(Assembly.GetAssembly(typeof(HdtRepository))).InSameNamespaceAs<HdtRepository>().WithService.DefaultInterfaces().LifestyleTransient()
);
}我的基本存储库看起来是这样的:
public abstract class RepositoryBase<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey> where TEntity : Entity<TPrimaryKey>
{
/// <summary>
/// Gets the NHibernate session object to perform database operations.
/// </summary>
public ISession Session { get; set; }
/// <summary>
/// Used to get a IQueryable that is used to retrive object from entire table.
/// </summary>
/// <returns>IQueryable to be used to select entities from database</returns>
public IQueryable<TEntity> GetAll()
{
return Session.Query<TEntity>();
}
/// <summary>
/// Gets an entity.
/// </summary>
/// <param name="key">Primary key of the entity to get</param>
/// <returns>Entity</returns>
public TEntity Get(TPrimaryKey key)
{
return Session.Get<TEntity>(key);
}
/// <summary>
/// Inserts a new entity.
/// </summary>
/// <param name="entity">Entity</param>
public void Insert(TEntity entity)
{
Session.Save(entity);
}
/// <summary>
/// Updates an existing entity.
/// </summary>
/// <param name="entity">Entity</param>
public void Update(TEntity entity)
{
Session.Update(entity);
}
/// <summary>
/// Deletes an entity.
/// </summary>
/// <param name="id">Id of the entity</param>
public void Delete(TPrimaryKey id)
{
Session.Delete(Session.Load<TEntity>(id));
}
}当我插入一个实体时,一切都正常工作。当我将Session.Flush()添加到更新方法中时,Update是正常工作的。
这是从Ajax调用并执行插入或更新的mehtod。
[Authorize]
[ValidateInput(false)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public JsonNetResult CreateOrUpdateTimeRecord(TimeRecord tr)
{
TimeRecord trLocal;
if (tr.Id == -1 || tr.Id == 0)
{
trLocal = new TimeRecord();
trLocal.Description = tr.Description;
trLocal.StartTime = tr.StartTime;
trLocal.EndTime = tr.EndTime;
trLocal.User = _userRepo.Get(tr.User.Id);
trLocal.Hdt = _hdtRepo.Get(tr.Hdt.Id);
_timeRepo.Insert(trLocal);
}
else
{
trLocal = _timeRepo.Get(tr.Id);
trLocal.Description = tr.Description;
trLocal.StartTime = tr.StartTime;
trLocal.EndTime = tr.EndTime;
_timeRepo.Update(trLocal);
}
return new JsonNetResult() { Data = trLocal};
}我不明白为什么这适用于插入而不是更新。我必须关心交易和开放/关闭会话吗?我以为"LifestylePerWebRequest“会为我做到这一点。
干杯,斯特凡
发布于 2013-12-27 20:42:45
编辑:(我最初的回答有部分错误)
您的实现实际上应该运行良好(只是测试了它)。虽然我可以再现更新不会刷新的行为,但是会话对象被正确地处理了。
LifestylePerWebRequest实际上很好地处理了这个问题,每当请求结束时,它就会释放会话。因此,必须将请求句柄添加到web.config等.所以温莎家族非常清楚,ISession是一次性的,它必须把它处理掉。
这是因为会话的FlushMode。
默认模式是Auto,它可能不是您想要的,因为您不能依赖存储的更改(特别是使用更新调用)。
您可以更改创建的会话对象的FlushMode,或者使用事务,这是我推荐的。
让我们看一下下面的示例:
var session = container.Resolve<ISession>();
var obj = new Paper()
{
Author = "Author",
Description = "Description",
};
session.Save(obj);
obj.Author = "Author2";
session.Update(obj);在这种情况下,更新将永远不会刷新/存储在数据库中。我猜这就是你目前的行为。
现在,让我们在它周围添加一个事务:
var session = container.Resolve<ISession>();
using (var transaction = session.BeginTransaction())
{
var obj = new Paper()
{
Author = "Author",
Description = "Description",
};
session.Save(obj);
obj.Author = "Author2";
session.Update(obj);
transaction.Commit();
}现在,这些更改将被确定地保存下来。
https://stackoverflow.com/questions/20804005
复制相似问题