是否把一切反对延迟加载的想法的事务工作不是nhibernates建议? [英] Doesn't nhibernates suggestion of putting everything in a transaction work against the idea of lazy loading?

查看:161
本文介绍了是否把一切反对延迟加载的想法的事务工作不是nhibernates建议?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个asp.net MVC的网站,我想了解各地的交易和延迟加载推荐的做法。

I have an asp.net-mvc site and i am trying to understand the recommended practice around transactions and lazy loading.

在做围绕implementating NHibernate的二级缓存,凭经验研究一个事务包裹周围的一切(见的这里和这里)。我想,因为他们似乎是在给定的延迟查询执行赔率调和这点与如何延迟加载工作。

When doing research around implementating nhibernate second level cache, one rule of thumb is around wrapping everything in a transaction (see here and here). I am trying to reconcile this point with how lazy loading works because they seems to be at odds given deferred query execution.

可以说我有一个查询,看起来像这样。

Lets say i have a query that looks like this . .

我有两个实体:


  1. 项目

  2. 所有者

下面是一个交易查询

public CacheTestViewModel GetCacheTestViewModel()
{
    var vm = new CacheTestViewModel();
    var session = Repository.Session;
    using (var tx = session.BeginTransaction())
    {
        vm.Projects = Repository.Session.Query<Project>().Cacheable()

        tx.Commit();
    }
    return vm;
}

但在我看来,我有以下的code:

but in my view I have the following code:

 <% foreach (var project in Model.Projects {%>
        <% = project.Owner %>
 <%} %>

所以需要因延迟加载的时候,但审查NHibernate的探查的时候,看来这些查询发生后事务提交做是为了让想看看是否能在第一时间打破原则,即查询所有者对象。看起来这将永远是与任何迟缓装载的问题(无论是取(),选择()或取(),选择()。批()

so that queries the Owner object when required due to lazy loading but when reviewing nhibernate profiler, it appears that these queries are happening AFTER the transaction commit is done so wanted to see if that breaks the principle in the first place. It seems like this will always be an issue with any lazy loading (either Fetch().Select() or Fetch().Select().Batch()

什么是推荐的做法在这里?

What is the recommended practice here?

推荐答案

您应该创建一个重新的视图需要呈现present一切的ViewModels。你不应该从视图中,如果在所有可能的发出数据库查询。以上总结在这里的链接:

You should create ViewModels that represent everything that the View needs to be rendered. You should not be issuing database queries from the view if at all possible. To summarize the link above here:


      
  • 它增加到数据库的连接必须是时间
      打开。该建议是保持打开只为期限
      的行动,而不是在整个请求的寿命。

  •   
  • 这使它
      更难以了解什么是对数据的要求
      特别行动。

  •   
  • 当写的意见,你不应该打扰
      与思考的持久性,或查询的数量,你
      意见产生。

  •   
  • 的意见往往是最多变的部分
      中的应用,以及具有从应用程序发出查询
      次,则可能对应用程序的方式显著变化
      版本之间的数据访问模式。

  •   
  • 大多数情况下,从查询
      从意见延迟加载,选择N + 1或类似的不良做法造成的。

  •   
  • It increase the time that the connection to the database have to be open. The recommendation is to keep that open only for the duration of the action, not throughout the lifetime of the request.
  • It make it that much harder to understand what are the data requirements for a particular action is.
  • When writing views, you shouldn't be bothered with thinking about persistence, or the number of queries that you views are generating.
  • The views are often the most changeable parts in the application, and having the application issue queries from the views may result in significant changes to the way the application data access pattern between revisions.
  • Most often, queries from the views result from lazy loading, Select N+1 or similar bad practices.

我们强烈建议你避免在生成查询
  视图,而是执行的操作您所有的疑问,并提供
  内存只能访问视图为他们呈现自己。

We strongly recommend that you'll avoid generating queries in the view, instead, perform all your queries in the action, and provide in memory access only to the view for them to render themselves.

(在最后一点上我的重点)。

(Emphasis on the last point mine).

这样做的实际意义是你应该的的是在视图中延迟加载任何东西。所以,你该怎么办呢?这是视图模型层的用武之地,你应该完全填充瘦视图模型您所需要的信息,然后渲染与视图。

The practical implications of this are that you should not be lazy loading anything in a view. So what should you do instead? This is where the ViewModel layer comes in. You should be fully populating a thin ViewModel with the information you need and then rendering the view with that.

此外,的ViewModels甚至不应该的包含的与NHibernate映射类(这似乎是你在你的例子做什么)。

Furthermore, ViewModels shouldn't even contain classes mapped with NHibernate (this appears to be what you're doing in your example).

有了这一切记住我会改变你目前的code:

With all this in mind I would change your current code:

public class CacheTestViewModel 
{
    public List<ProjectViewModel> Projects { get; set; }
}

public class ProjectViewModel
{
    public string Owner { get; set; }
    /* etc. */
}

..然后你code来填充这些的ViewModels:

.. And then your code to populate those ViewModels:

public CacheTestViewModel GetCacheTestViewModel()
{
    var vm = new CacheTestViewModel();
    var session = Repository.Session;
    using (var tx = session.BeginTransaction())
    {
        var projects = Repository.Session.Query<Project>().Cacheable();

        foreach (var project in project)
        {
            vm.Projects.Add(new ProjectViewModel { Owner = project.Owner.Name });
        }

        tx.Commit();
    }
    return vm;
}

现在,你可能会想:哎呀,这是一个很大code的映射域实体的ViewModels。我可以看到失控。你会是对的。有一个叫 AutoMapper ,您可以使用半自动化的映射。库

Now you might be thinking "gee, that's a lot of code to map domain entities to ViewModels. I can see that getting out of hand." You'd be right about that. There's a library called AutoMapper that you can use to semi-automate your mappings.

这篇关于是否把一切反对延迟加载的想法的事务工作不是nhibernates建议?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆