代码之家  ›  专栏  ›  技术社区  ›  Alex

使用带有Fluent NHibernate的通用存储库模式

  •  13
  • Alex  · 技术社区  · 14 年前

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

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

    但是,我想使用fluent nhibernate代替linq to sql(当然还有nhibernate.linq)

    这可行吗?

    我该如何进行配置? 我的映射定义会去哪里……?

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

    此外,例如在“product”表上,我是否要创建一个“productmanager”类,该类具有以下方法:

    获取产品、获取所有产品等…

    任何指针都会被大量接收。

    2 回复  |  直到 14 年前
        1
  •  22
  •   Paco    14 年前

    在我看来(在某些人看来也是如此),存储库应该是一个接口,它在一个模仿收集接口的接口中隐藏数据访问。这就是为什么存储库应该是iQuery和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);
      }   
    }
    

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

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

    我将特定于nhibernate的工作执行单元的会话用作存储库的会话:

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

    在一个实际的应用程序中,我使用了一个更复杂的存储库接口,它提供了一些方法,比如分页、预加载、规范模式、对nhibrante使用的其他查询方法的访问,而不仅仅是linq。NHibernate主干中的LINQ实现对于我需要做的大多数查询都足够好。

        2
  •  1
  •   Community kfsone    7 年前

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

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

    我已经成功地使用了NHibernate模式,并且没有发现任何真正的缺点。

    要点是,真正的通用存储库有点像是一条红鲱鱼,但同样的好处可以通过稍微不同地考虑问题来实现。

    希望有帮助。