C# 在请求结束时,如何在控制器内执行某些操作?

C# 在请求结束时,如何在控制器内执行某些操作?,c#,asp.net-mvc-3,nhibernate,C#,Asp.net Mvc 3,Nhibernate,我想在控制器请求结束时,也就是在呈现视图和所有对象之后,处理NHibernate会话对象。我应该在哪里执行此操作?您可以创建自己的并覆盖 只是为了在控制器请求结束时做出反应,我不太了解NHibernate 编辑:正如jgauffin中提到的,您还可以覆盖控制器中执行的OnResultExecuted。您可以创建自己的并覆盖 只是为了在控制器请求结束时做出反应,我不太了解NHibernate 编辑:正如jgauffin中提到的,您还可以覆盖控制器中执行的OnResultExecuted。处理NHi

我想在控制器请求结束时,也就是在呈现视图和所有对象之后,处理NHibernate会话对象。我应该在哪里执行此操作?

您可以创建自己的并覆盖

只是为了在控制器请求结束时做出反应,我不太了解NHibernate

编辑:正如jgauffin中提到的,您还可以覆盖控制器中执行的OnResultExecuted。

您可以创建自己的并覆盖

只是为了在控制器请求结束时做出反应,我不太了解NHibernate


编辑:正如jgauffin中提到的,您还可以覆盖控制器中执行的OnResultExecuted。

处理NHibernate会话不是控制器的责任。理想情况下,在处置存储库时,它需要是您的存储库或/和IoCContainer。
与上面的答案相同,我不太了解NHibernate,但我会遵循这种模式。

处理NHibernate会话不是您的管理员的责任。理想情况下,在处置存储库时,它需要是您的存储库或/和IoCContainer。
与上面的答案相同,我对NHibernate了解不多,但我会遵循这种模式。

一篇很长的帖子,但我做了以下几点:-

public class Repository<T> : IRepository<T>
{
    private readonly ISessionFactory SessionFactory;
    public Repository(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
    }
    public ISession Session
    {
        get
        {
            return SessionFactory.GetCurrentSession();
        }
    }
    public T Get(long id)
    {
        return Session.Get<T>(id);
    }
}
在我的global.asax.cs中

public static ISessionFactory SessionFactory { get; set; }
然后定义应用内启动

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);

    var nhConfig = new Configuration().Configure();
    SessionFactory = nhConfig.BuildSessionFactory();
}
然后创建该类:-

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class NHSession : ActionFilterAttribute
{
    public NHSession()
    {
        Order = 100;
    }

    protected ISessionFactory sessionFactory
    {
        get
        {
                return MvcApplication.SessionFactory;
        }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var session = sessionFactory.OpenSession();
        CurrentSessionContext.Bind(session);
        session.BeginTransaction();
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var session = CurrentSessionContext.Unbind(sessionFactory);
        if (session != null)
        {
            if (session.Transaction.IsActive)
            {
                try
                {
                    session.Transaction.Commit();
                }
                catch
                {
                    session.Transaction.Rollback();
                }
            }
            session.Close();
        }
    }
}
然后,我的通用存储库看起来大致如下:-

public class Repository<T> : IRepository<T>
{
    private readonly ISessionFactory SessionFactory;
    public Repository(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
    }
    public ISession Session
    {
        get
        {
            return SessionFactory.GetCurrentSession();
        }
    }
    public T Get(long id)
    {
        return Session.Get<T>(id);
    }
}

这样我就能够在请求中使用工作单元。基本上,一个请求进入并启动一个会话,sessionfactory被传递到Repositoryes的ctor中。。。我在这里使用DI,但这是可选的。如果检测到错误,则在请求结束时提交会话(如果没有),则回滚会话。我建议您使用NHProf,因为它可以帮助您了解会话管理,即如果会话管理设置不正确的话。

这篇文章很长,但我做了以下几点:-

public class Repository<T> : IRepository<T>
{
    private readonly ISessionFactory SessionFactory;
    public Repository(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
    }
    public ISession Session
    {
        get
        {
            return SessionFactory.GetCurrentSession();
        }
    }
    public T Get(long id)
    {
        return Session.Get<T>(id);
    }
}
在我的global.asax.cs中

public static ISessionFactory SessionFactory { get; set; }
然后定义应用内启动

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);

    var nhConfig = new Configuration().Configure();
    SessionFactory = nhConfig.BuildSessionFactory();
}
然后创建该类:-

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class NHSession : ActionFilterAttribute
{
    public NHSession()
    {
        Order = 100;
    }

    protected ISessionFactory sessionFactory
    {
        get
        {
                return MvcApplication.SessionFactory;
        }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var session = sessionFactory.OpenSession();
        CurrentSessionContext.Bind(session);
        session.BeginTransaction();
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var session = CurrentSessionContext.Unbind(sessionFactory);
        if (session != null)
        {
            if (session.Transaction.IsActive)
            {
                try
                {
                    session.Transaction.Commit();
                }
                catch
                {
                    session.Transaction.Rollback();
                }
            }
            session.Close();
        }
    }
}
然后,我的通用存储库看起来大致如下:-

public class Repository<T> : IRepository<T>
{
    private readonly ISessionFactory SessionFactory;
    public Repository(ISessionFactory sessionFactory)
    {
        SessionFactory = sessionFactory;
    }
    public ISession Session
    {
        get
        {
            return SessionFactory.GetCurrentSession();
        }
    }
    public T Get(long id)
    {
        return Session.Get<T>(id);
    }
}

这样我就能够在请求中使用工作单元。基本上,一个请求进入并启动一个会话,sessionfactory被传递到Repositoryes的ctor中。。。我在这里使用DI,但这是可选的。如果检测到错误,则在请求结束时提交会话(如果没有),则回滚会话。我建议您使用NHProf,因为它可以帮助您了解会话管理,即如果设置不正确的话。

我们需要先了解您是如何启动它的。通常,在using中包装任何datacontext都可以确保它被释放,但如果您使用其他IOC容器并将会话开始绑定到其他内容,则有一个非常不同的解决方案。我们需要知道您首先是如何启动它的。通常,在using中包装任何datacontext都可以确保它已被释放,但是如果您正在使用其他IOC容器并将会话开始绑定到其他内容,然后是一个非常不同的解决方案。+1您还应该提到,也可以覆盖控制器中执行的OnResultExecuted,因为他可能在controllerYep中有一个成员字段,您是对的,但我考虑了一个解决方案,他可以将属性放置到所有控制器。但是我们都不知道他的代码是什么样子的:谢谢你的添加。+1你还应该提到,也可以覆盖控制器中执行的OnResultExecuted,因为他可能在controllerYep中有一个成员字段,你是对的,但我想了一个解决方案,他可以将属性放在所有控制器上。但我们都不知道他的代码是什么样子:谢谢你的添加。