【问题标题】:Using a Generic Repository pattern with fluent nHibernate将通用存储库模式与流利的 nHibernate 一起使用
【发布时间】:2011-02-04 23:43:49
【问题描述】:

我目前正在开发一个中型应用程序,它将访问不同站点上的 2 个或更多 SQL 数据库等...

我正在考虑使用类似的东西: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

但是,我想使用流畅的 nHibernate 来代替 Linq-to-SQL(当然还有 nHibernate.Linq)

这可行吗?

我将如何进行配置? 我的映射定义会去哪里等等...?

此应用程序最终将具有许多方面 - 来自 WebUI、WCF 库和 Windows 应用程序/服务。

另外,例如在“产品”表上,我是否会创建一个“ProductManager”类,其方法如下:

GetProduct、GetAllProducts 等...

任何指针都大大收到。

【问题讨论】:

  • 旁注:Fluent NHibernate 只是一种配置 NHibernate 映射的方法;它不是一个不同的框架,它与存储库实现无关。

标签: c# nhibernate repository-pattern


【解决方案1】:

在我看来(以及其他一些人的意见),存储库应该是一个接口,它在一个模仿集合接口的接口中隐藏数据访问。这就是存储库应该是 IQueryable 和 IEnumerable 的原因。

public interface IRepository<T> : IQueryable<T>
{
  void Add(T entity);
  T Get(Guid id);
  void Remove(T entity);
}

public class Repository<T> : IQueryable<T>
{
  private readonly ISession session;

  public Repository(ISession session)
  {
    session = session;
  }

  public Type ElementType
  {
    get { return session.Query<T>().ElementType; }
  }

  public Expression Expression
  {
    get { return session.Query<T>().Expression; }
  }

  public IQueryProvider Provider
  {
    get { return session.Query<T>().Provider; } 
  }  

  public void Add(T entity)
  {
    session.Save(entity);
  }

  public T Get(Guid id)
  {
    return session.Get<T>(id);
  }

  IEnumerator IEnumerable.GetEnumerator()
  {
    return this.GetEnumerator();
  }

  public IEnumerator<T> GetEnumerator()
  {
    return session.Query<T>().GetEnumerator();
  }

  public void Remove(T entity)
  {
    session.Delete(entity);
  }   
}

我没有在存储库本身中实现类似 SubmitChanges 的方法,因为我想一次提交用户的一个操作使用的多个存储库的更改。我把事务管理隐藏在一个工作单元界面中:

public interface IUnitOfWork : IDisposable
{
  void Commit();
  void RollBack();
}

我使用 NHibernate 特定工作单元实现的会话作为存储库的会话:

public interface INHiberanteUnitOfWork : IUnitOfWork
{
  ISession Session { get; } 
}

在实际应用程序中,我使用更复杂的存储库接口,其中包含诸如分页、预加载、规范模式、访问 NHiberante 使用的其他查询方式等方法,而不仅仅是 linq。 NHibernate 主干中的 linq 实现对于我需要执行的大多数查询来说都足够好。

【讨论】:

  • 太棒了!简单,IQueryable 和一个工作单元。这确实适合存储库模式“内存中域对象集合 [...]”的定义。添加一些 DI,它变得非常有用!干得好 - :)
  • 我们能看到“更复杂的存储库接口”是什么样的吗?这很好,但我也希望能够做“诸如分页、急切加载、规范模式、访问 NHiberante 使用的其他查询方式而不仅仅是 linq 之类的事情”。另外,如果您能演示一下您是如何使用它的,那将会很有帮助。提前致谢!
  • 我很好奇您如何定义 IRepository 以利用 NHibernate 的其他查询方法 - 同时保持其通用性。
  • @Chris Klepeis 我在存储库中没有使用太多其他查询方法。我更喜欢在 ISession 上使用它们来跳过大多数情况下无用的抽象
  • 我想知道你 UintOfWork 什么时候调用 Commit/Rollback?
【解决方案2】:

以下是我对通用存储库的看法:

Advantage of creating a generic repository vs. specific repository for each object?

我已经成功地将这种模式与 NHibernate 一起使用,并且没有发现任何真正的缺点。

要点是,真正通用的存储库有点绕圈子,但通过稍微不同的思考问题,可以实现相同的好处。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多