【问题标题】:Unit of Work Method with Lazy Loading concerns, nHibernate, ASP.NET MVC, Castle Windsor具有延迟加载问题的工作单元方法、nHibernate、ASP.NET MVC、Castle Windsor
【发布时间】:2010-12-17 14:01:59
【问题描述】:

在 C# 中给出一个相当简单的结构...

class Member
{
 virtual string Email { get; set; }
 virtual IList<Character> Characters { get; set; }
}

class Character
{
 virtual string Name { get; set; }
}

interface IMemberRepository
{
 MemberCreateStatus CreateMember(string email, string password);
 bool ValidateMember(string email, string password);
 Member RetrieveMember(string email);
 void SaveMember(Member member);
}

interface ICharacterRepository
{
 Character CreateCharacter(string name);
}


class MemberRepository : IMemberRepository
{
 private readonly ISessionFactory sessionFactory;

 public MemberRepository(ISessionFactory sessionFactory)
 {
    this.sessionFactory = sessionFactory;
 }

 // 
 public Member RetrieveMember(string email)
 {
    using(var session = sessionFactory.OpenSession())
    {
      return // member retrieval query
    }
 }
}

我有一个 ASP.NET MVC 应用程序设置为使用 nHibernate(流畅配置)和 Castle.Windsor 用于 IoC。这很好用,但问题就在这里。

延迟加载

默认情况下,IList&lt;Character&gt; 在大多数 ORM(nHibernate、Entity Framework 等)中都是延迟加载的 - 现在这不是一件坏事,但我对如何处理这种情况有很多困惑。

  • 我想将Character 添加到Member。从逻辑上讲,我会使用Member.Characters.Add(n);,然后调用MemberRepository.SaveMember(m);

由于工作单元概念,这现在是个问题。我应该创建一个Session,完成工作,然后在返回结果后将其销毁。效果很好,但现在我有以下对象......

Member

  • nHibernate 延迟加载代理 (IList&lt;Character&gt;)
  • Email

那么,我在我的Controller 中调用var member = memberRepository.RetrieveMember(email);,然后我调用member.Characters.Add(character); 这就是混乱的来源。

集合不存在,因为它是延迟加载的,Session 已被释放。

那么,答案是什么?当然,我可以将我的IList&lt;Character&gt; 设置为不延迟加载,但这有点愚蠢。如果阻碍了基本的设计结构,世界上最大的 ORM 库之一就不会使用延迟加载。 UnitOfWork 的这个概念如何在 IoCIRepository&lt;T&gt; 模式和注入依赖中发挥作用?

我的第一个想法是将任务抽象到存储库,并在IMemberRepository 中包含一个AddCharacter(Character character) 方法,但我现在被告知“不是存储库的用途”。所以我不太确定从现在开始该怎么做。以编程方式我知道许多解决方案,但我需要了解正确解决方案是什么才能符合标准。

nHibernate 的 Session 类有一个名为 Persist(object obj) 的方法,我使用 UnitOfWork 模式进行了工作 - 但据我所知,此方法删除了任何它的延迟加载方面应用于。如果那是一个电话会议的基础,那会很好 - 但我知道我不能这样做。我不能直接与我的Session 交谈——只有我的Repository 类应该被允许与SessionFactory 通信。所以我现在真的很困惑。

【问题讨论】:

    标签: asp.net-mvc nhibernate fluent-nhibernate castle-windsor lazy-loading


    【解决方案1】:

    您应该将 ISession 传递给存储库类构造函数。 session-per-request 模式通常用于 Web 应用程序,以便 ISession 的生命周期与 HTTP 请求相同。在我看来,存储库类不应该访问 SessionFactory,并且应该始终将 ISession 作为依赖项提供。

    【讨论】:

    • 那么,我将如何使用UnitOfWork(ISessionFactory) 和 Castle.Windsor 与我的各种控制器进行设置?什么应该得到ISessionFactory?我想在我的控制器中使用它吗?我无法使用无参数构造函数实例化 UnitOfWork... 我不太了解这将如何与 Windsor 一起使用。
    • 我不知道如何与温莎一起使用。 ISessionFactory 应该在应用程序启动时初始化。 ISession 应该在每个请求上创建。此搜索应为您指明正确的方向:google.com/search?q=windsor+nhibernate+session-per-request
    • 对不起.. 这没什么帮助。
    • ?搜索结果中的第 5 个链接直接解决了您的问题:stackoverflow.com/questions/2276408/…
    • 实际上,这确实有更多帮助。我知道我现在需要更具体地问什么。我认为这解决了这个特定问题,但开辟了一个新问题。我会在应得的地方给予信任,并为新问题提出新问题。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    相关资源
    最近更新 更多