具有流利的Nhibernate的存储库模式

时间:2016-11-08 10:48:05

标签: fluent-nhibernate repository-pattern

大家好我已经使用fluentNHibernate成功实现了存储库模式但我有一个关注点是 ExposeConfiguration 当我删除它时所有方法都正常工作但是当我添加它,它重置数据库中的表。所以我需要你看看并给我任何关于实施的说明,所以这是我的工作单位

 public class UnitOfWork 
{

    public static ISession  NhibernateHelper()
    {
        ISessionFactory _sessionFactory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2012.ConnectionString(@"Data Source=WAAIL-PC\COMPUTERENGINEER;Initial Catalog=TSQL2012;User ID=sa;Password=12345678Ce").ShowSql())
            .Mappings(x => x.FluentMappings.AddFromAssemblyOf<UsersMap>())
           //.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true)) //when i removed this line it doesn't
          //remove the elements from the db
            .BuildSessionFactory();

       return _sessionFactory.OpenSession();

    }}

这是我的存储库模式:

public class Repository<T> :IRepository<T> where T :BaseEntity
{

    public Repository(/*IUnitOfWork unitOfWork*/)
    {
        //_unitOfWork = (UnitOfWork)unitOfWork;
    }

    public List<T> GetAll()
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            return Session.Query<T>().ToList();
        }
    }

    public T GetById(int id)
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            return Session.Get<T>(id);
        }
    }

    public T Insert(T entity)
    {
        try
        {
            using (ISession Session = UnitOfWork.NhibernateHelper())
            {
                using (ITransaction Transaction = Session.BeginTransaction())
                {
                    Session.Save(entity);
                    Transaction.Commit();
                }
            }
            return entity;
        }
        catch (Exception)
        {

            throw;
        }
    }

    public void Update(T entity)
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            using (ITransaction Transaction = Session.BeginTransaction())
            {
                Session.Update(entity);
                Transaction.Commit();
            }
        }
    }

    public void Delete(int id)
    {
        using (ISession Session = UnitOfWork.NhibernateHelper())
        {
            using (ITransaction Transaction = Session.BeginTransaction())
            {
                Session.Delete(Session.Load<T>(id));
                Transaction.Commit();
            }
        }
    }
}

这是我的usersService

public class UsersService : IUsersService
{
    private readonly IRepository<Users> _Repository;

    #region Constructor
    public UsersService(IRepository<Users> Repository)
    {
        _Repository = Repository;
    }
    #endregion

    #region Service Implementation

    public List<Users> GetListAll()
    {
        return _Repository.GetAll().ToList();
    }

    public Users GetById(int Id)
    {
        return _Repository.GetById(Id);
    }

    public Users Insert(Users user)
    {
        return _Repository.Insert(user);
    }

    public void Update(Users user)
    {
        _Repository.Update(user);
    }
    public void Delete(int Id)
    {
        _Repository.Delete(Id);
    }

    //public int execute()
    //{
    //    return _Repository.execute();
    //}


}

所以我需要知道的是Expose_configuration方法导致表重置的原因......其次,我是否正确地在这个实现中移动。 如果你们有任何改进的更新请告诉我.. 最好的问候。

1 个答案:

答案 0 :(得分:2)

邪恶在于细节

您写道:

  

... ExposeConfiguration当我删除它时所有方法都可以正常工作,但是当我添加它时,它会重置数据库中的表。

这是非常正常的操作方式,因为如果我们查找NHiberate的SchemaExportCreate方法签名,它会显示:

public void Create(Action<string> scriptAction, bool execute)

它的文档说明Create()

  

运行架构创建脚本

关于它的参数:

  

scriptAction - 将为生成的ddl的每一行调用的操作。

     

执行 - 如果应该对数据库执行ddl。

你称之为:

.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true))

您的问题在于您将true传递给execute参数,该参数将在文档中说明 - 执行模式创建脚本,其中可能包括删除和重新审核现有数据库对象。 / p>

为什么要制造恶魔?

关于你的第二个想法,我真的看不到为你的代码添加另一层间接的好处,而这就是你召唤不需要的恶魔的地方。

NHibernate ORM本身 是一个抽象本身,为什么要在它周围添加一个更通用的呢?你的Repository<T>只是简单地调用已经实现的通用NHibernate方法...有点像Proxy来隐藏NHibernate,如果有意请原谅我,但它看起来不是。

最后一点:您的UsersService课程首先违反了Single responsibility principle,并通过维护和测试让您的生活更难。其次,这个类也不仅仅是调用存储库来返回值的代理。

让我说明问题:

  1. 客户来电UsersService.GetById(Id)
  2. 服务电话_Repository.GetById(Id)
  3. 您的通用抽象存储库调用NHibernates Session.Get<T>(id)
  4. 你看到了问题吗?

    在这种情况下,使用可能对您有帮助的模式,即Command Query Separation,会更容易。

    您的命令负责写入,有关读取的查询以及两者都适合您的用例。

    您之前可以阅读我关于queriescommands的答案。