将通用存储库模式与流利的nHibernate结合使用 [英] Using a Generic Repository pattern with fluent nHibernate

查看:68
本文介绍了将通用存储库模式与流利的nHibernate结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently developing a medium sized application, which will access 2 or more SQL databases, on different sites etc...

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

I am considering using something similar to this: http://mikehadlow.blogspot.com/2008/03/using-irepository-pattern-with-linq-to.html

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

However, I want to use fluent nHibernate, in place of Linq-to-SQL (and of course nHibernate.Linq)

这可行吗?

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

How would I go about configuring this? Where would my mapping definitions go etc...?

该应用程序最终将具有多个方面-来自WebUI,WCF库和Windows应用程序/服务.

This application will eventually have many facets - from a WebUI, WCF Library and Windows applications / services.

例如,在产品"表上,我还会创建一个"ProductManager"类,该类具有以下方法:

Also, for example on a "product" table, would I create a "ProductManager" class, that has methods like:

GetProduct,GetAllProducts等...

GetProduct, GetAllProducts etc...

任何指针都可以收到.

推荐答案

在我看来(在其他一些人看来也是这样),存储库应该是一个接口,该接口在模拟收集接口的接口中隐藏了数据访问.这就是为什么存储库应该是IQueryable和IEnumerable的原因.

In my opinion (and in some other peoples opinion as well), a repository should be an interface that hides data access in an interface that mimics a collection interface. That's why a repository should be an IQueryable and 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的方法,因为我想一次提交用户的一项操作所使用的多个存储库的更改.我将事务管理隐藏在工作单元界面中:

I do not implement a SubmitChanges like method in the repository itself, because I want to submit the changes of several repositories used by one action of the user at once. I hide the transaction management in a unit of work interface:

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

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

I use the session of an NHibernate specific unit of work implementation as session for the repositories:

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

在实际的应用程序中,我使用了更复杂的存储库接口,并使用了诸如分页,快速加载,规范模式,访问NHiberante所使用的其他查询方式(而不仅仅是linq)之类的方法. NHibernate干线中的linq实现足以满足我需要执行的大多数查询.

In a real application, I use a more complicated repository interface with methods for things like pagination, eager loading, specification pattern, access to the other ways of querying used by NHiberante instead of just linq. The linq implementation in the NHibernate trunk works good enough for most of the queries I need to do.

这篇关于将通用存储库模式与流利的nHibernate结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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