【问题标题】:Repository Pattern with Fluent Nhibernate使用 Fluent Nhibernate 的存储库模式
【发布时间】:2016-11-08 10:48:04
【问题描述】:

大家好,我已经使用 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();
            }
        }
    }
}

这是我的用户服务

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 方法会导致表重置......其次,我在这个实现中是否以正确的方式移动。 如果你们有任何改进的更新,请告诉我.. 最好的问候。

【问题讨论】:

    标签: fluent-nhibernate repository-pattern


    【解决方案1】:

    邪恶在于细节

    你写道:

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

    这是非常正常的操作方式,因为如果我们查看 NIBerate 的 SchemaExport classes Create 方法签名,它会显示:

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

    文档指出Create():

    运行架构创建脚本

    关于它的参数:

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

    执行 - 是否应该针对数据库执行 ddl。

    你称它为:

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

    您的问题在于您将 true 传递给 execute 参数,这将 - 如文档中所述 - 执行架构创建脚本,其中可能包括现有数据库对象的删除和重新创建。

    为什么要制造恶魔?

    关于你的第二个想法,我真的认为在你的代码中添加另一层间接没有任何好处,这就是你召唤不需要的恶魔的地方。

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

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

    让我来说明问题:

    1. 客户端调用UsersService.GetById(Id)
    2. 服务调用_Repository.GetById(Id)
    3. 您的通用抽象存储库调用 NHibernates Session.Get&lt;T&gt;(id)

    你发现问题了吗?

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

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

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

    【讨论】:

    • 那么你的意思是只要我们实现了fluentNHibernate,那么存储库模式就没有必要了吗?对吧?
    • 是的,如果没有什么强制你拥有额外的抽象层,那就对了!
    猜你喜欢
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多