windsor nHibernate ISession

时间:2013-12-27 16:21:24

标签: asp.net-mvc asp.net-mvc-4 nhibernate castle-windsor castle

我有一个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));
    }
}

插入实体时,一切正常。 当我向我的Update方法添加Session.Flush()时,更新是onyl工作。

这是从Ajax调用并执行插入或更新的方法。

 [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”会为我做这件事。

干杯, 斯蒂芬

1 个答案:

答案 0 :(得分:1)

:编辑:(我最初的回答是部分错误的)

你实现应该工作正常(只是测试它)。 虽然我可以重现更新未刷新的行为,尽管会话对象被正确放置

LifestylePerWebRequest实际上处理好了,它会在请求结束时处理会话。因此你必须将请求句柄添加到web.config等...所以windsor的东西完全知道ISession是一次性的,它必须处理它......

这是因为会话的FlushMode。

默认模式是自动,这可能不是您想要的,因为您不能依赖存储的更改(特别是使用更新调用)。

您可以更改已创建的会话对象的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();
}

现在可以保存更改。