Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 使用RavenDB和ASP.NET MVC进行会话处理_Asp.net Mvc_Ravendb - Fatal编程技术网

Asp.net mvc 使用RavenDB和ASP.NET MVC进行会话处理

Asp.net mvc 使用RavenDB和ASP.NET MVC进行会话处理,asp.net-mvc,ravendb,Asp.net Mvc,Ravendb,我有一个服务类UserService,它使用AutoFac获取IDocumentStore的一个实例。这很好,但现在我看到的代码如下: public void Create(User user) { using (var session = Store.OpenSession()) { session.Store(user); session.SaveChanges(); } } public class RavenController

我有一个服务类UserService,它使用AutoFac获取IDocumentStore的一个实例。这很好,但现在我看到的代码如下:

public void Create(User user)
{
    using (var session = Store.OpenSession())
    {
        session.Store(user);
        session.SaveChanges();
    }
} 
public class RavenController : Controller
{
    public IDocumentSession Session { get; set; }
    protected IDocumentStore _documentStore;

    public RavenController(IDocumentStore documentStore)
    {
        _documentStore = documentStore;
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Session = _documentStore.OpenSession();
        base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        using (Session)
        {
            if (Session != null && filterContext.Exception == null)
            {
                Session.SaveChanges();
            }
        }
        base.OnActionExecuted(filterContext);
    }
}
public class HomeController : RavenController
{
    public HomeController(IDocumentStore store)
        : base(store)
    {

    }

    public ActionResult CreateUser(UserModel model)
    {
        if (ModelState.IsValid)
        { 
            User user = Session.Load<User>(model.email);
            if (user == null) { 
                // no user found, let's create it
                Session.Store(model);
            }
            else {
                ModelState.AddModelError("", "That email already exists.");
            }
        }
        return View(model);
    }
}
写入数据库的每个操作都使用相同的结构:

using (var session = Store.OpenSession())
{
    dosomething...
    session.SaveChanges();
}

消除这种重复代码的最佳方法是什么?

最简单的方法是在基本控制器上实现
OnActionExecuting
OnActionExecuted
,并使用它

让我们想象一下,您创建的
RavenController
如下所示:

public void Create(User user)
{
    using (var session = Store.OpenSession())
    {
        session.Store(user);
        session.SaveChanges();
    }
} 
public class RavenController : Controller
{
    public IDocumentSession Session { get; set; }
    protected IDocumentStore _documentStore;

    public RavenController(IDocumentStore documentStore)
    {
        _documentStore = documentStore;
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Session = _documentStore.OpenSession();
        base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        using (Session)
        {
            if (Session != null && filterContext.Exception == null)
            {
                Session.SaveChanges();
            }
        }
        base.OnActionExecuted(filterContext);
    }
}
public class HomeController : RavenController
{
    public HomeController(IDocumentStore store)
        : base(store)
    {

    }

    public ActionResult CreateUser(UserModel model)
    {
        if (ModelState.IsValid)
        { 
            User user = Session.Load<User>(model.email);
            if (user == null) { 
                // no user found, let's create it
                Session.Store(model);
            }
            else {
                ModelState.AddModelError("", "That email already exists.");
            }
        }
        return View(model);
    }
}
然后,您只需在自己的控制器中执行以下操作,即从
RavenController
继承:

public void Create(User user)
{
    using (var session = Store.OpenSession())
    {
        session.Store(user);
        session.SaveChanges();
    }
} 
public class RavenController : Controller
{
    public IDocumentSession Session { get; set; }
    protected IDocumentStore _documentStore;

    public RavenController(IDocumentStore documentStore)
    {
        _documentStore = documentStore;
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Session = _documentStore.OpenSession();
        base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        using (Session)
        {
            if (Session != null && filterContext.Exception == null)
            {
                Session.SaveChanges();
            }
        }
        base.OnActionExecuted(filterContext);
    }
}
public class HomeController : RavenController
{
    public HomeController(IDocumentStore store)
        : base(store)
    {

    }

    public ActionResult CreateUser(UserModel model)
    {
        if (ModelState.IsValid)
        { 
            User user = Session.Load<User>(model.email);
            if (user == null) { 
                // no user found, let's create it
                Session.Store(model);
            }
            else {
                ModelState.AddModelError("", "That email already exists.");
            }
        }
        return View(model);
    }
}
公共类HomeController:RavenControl
{
公共家庭控制器(IDocumentStore)
:基地(商店)
{
}
public ActionResult CreateUser(用户模型)
{
if(ModelState.IsValid)
{ 
用户=Session.Load(model.email);
如果(user==null){
//找不到用户,让我们创建它
Session.Store(模型);
}
否则{
AddModelError(“,”该电子邮件已存在。“);
}
}
返回视图(模型);
}
}

很有趣,我发现一篇博客文章正好展示了这种技术

这确实比我所做的解释得多。我希望它能更好地帮助你


我读过类似的说明(ravendb教程中的某个地方),但我想将这种逻辑移到我的服务层中,因为我认为这不应该是我控制器的一部分。然后以同样的方式在DLL中实现它。我在我的存储库层上使用它,但我以前总是使用缓存层。我该怎么做?在我的服务类中,我没有可用的ActionExecuting和ActioneCcuted。确实没有,但您可以从
IDisposable
继承服务类,并在那里处置会话。在视图控制器上,您对需要访问数据库的所有控制器继续使用相同的基本控制器,但是在您的存储库层上处理或调用一次性方法。@balexandre如何处理并发异常?当抛出此异常时,您将向用户显示什么?当您使用PRG模式时,它会变得更有趣,然后呢?