NHibernate存储库模式问题

NHibernate存储库模式问题,nhibernate,repository-pattern,session-management,Nhibernate,Repository Pattern,Session Management,我正在应用程序中使用NHibernate和存储库模式。但不想使用UnitofWork模式 我的应用程序中有两种类型的表单。集合/选择器表单和实体表单 但是当一个表单从另一个表单中显示时,就会出现问题 当我执行任何与数据库相关的操作时,NHibernate会给我“一个具有相同标识符值的不同对象已与会话关联:XYZ”错误。这是由于CLR延迟调用Dispose方法造成的,据我猜测,我的问题的另一部分在会话管理中 如何更改存储库代码以解决问题 记住,我不想在我的存储库中公开单独的BeginTrans

我正在应用程序中使用NHibernate和存储库模式。但不想使用UnitofWork模式

我的应用程序中有两种类型的表单。集合/选择器表单和实体表单

但是当一个表单从另一个表单中显示时,就会出现问题

当我执行任何与数据库相关的操作时,NHibernate会给我“一个具有相同标识符值的不同对象已与会话关联:XYZ”错误。这是由于CLR延迟调用Dispose方法造成的,据我猜测,我的问题的另一部分在会话管理中

如何更改存储库代码以解决问题

记住,我不想在我的存储库中公开单独的BeginTransaction()、CommitTransaction()类函数。这些东西应该像我已经做的那样嵌入到每个方法{SaveOrUpdate()、Save()、Delete、Load()等}中

请告诉我,我怎样才能使事情顺利进行的小变化

我是这样做的:

选择器窗体的工作方式如下所示

private void btnPick_Click(object sender, EventArgs e)
        {
            CourseCollectionForm f = new CourseCollectionForm();
            f.FormViewMode = FormViewMode.MultiplePicker;
            f.ShowDialog();

            int totalCredits = 0;
            int totalHours = 0;

            FillDataGridViewWithCourses(f.PickedCourseCollection, ref totalCredits, ref totalHours);

            FillTotal(totalCredits, totalHours);
        }
public partial class DepartmentEntityForm : Form
    {
        private DepartmentRepository _deptRepository = null;
        private Department _currentDepartment = null;
        private FormViewMode _currentMode = FormViewMode.None;

        public DepartmentEntityForm(Department dept, FormViewMode mode)
        {
            InitializeComponent();

            _deptRepository = new DepartmentRepository();

            _currentDepartment = dept;
            _currentMode = mode;

            if(mode == FormViewMode.Edit)
            {
                MapObjectToControls();
            }
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {
            Department newDept;

            if (mode == FormViewMode.AddNew)
            {
                newDept = new Department();
            }
            else if(mode == FormViewMode.Edit)
            {
                newDept = _currentDepartment;
            }
            //.............
            //.............

            _deptRepository.SaveOrUpdate(newDept);
        }
    }
保存的工作方式是这样的

private void btnPick_Click(object sender, EventArgs e)
        {
            CourseCollectionForm f = new CourseCollectionForm();
            f.FormViewMode = FormViewMode.MultiplePicker;
            f.ShowDialog();

            int totalCredits = 0;
            int totalHours = 0;

            FillDataGridViewWithCourses(f.PickedCourseCollection, ref totalCredits, ref totalHours);

            FillTotal(totalCredits, totalHours);
        }
public partial class DepartmentEntityForm : Form
    {
        private DepartmentRepository _deptRepository = null;
        private Department _currentDepartment = null;
        private FormViewMode _currentMode = FormViewMode.None;

        public DepartmentEntityForm(Department dept, FormViewMode mode)
        {
            InitializeComponent();

            _deptRepository = new DepartmentRepository();

            _currentDepartment = dept;
            _currentMode = mode;

            if(mode == FormViewMode.Edit)
            {
                MapObjectToControls();
            }
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {
            Department newDept;

            if (mode == FormViewMode.AddNew)
            {
                newDept = new Department();
            }
            else if(mode == FormViewMode.Edit)
            {
                newDept = _currentDepartment;
            }
            //.............
            //.............

            _deptRepository.SaveOrUpdate(newDept);
        }
    }
我声明我的个人存储库如下:

FacultyRepository.cs
好的,伙计们!我已经很久没有发布我的问题了,没有人愿意回答

我通过在
SessionFactory
中设置
ISession static
解决了这个问题,并没有为每个存储库返回一个打开的
ISession
,而是只返回一个
static
ISession

public class Repository<T> : IRepository<T>
    {
        ISession _session;

        public Repository() 
        {
            _session = SessionFactory.GetOpenSession();
        }

        public T Get(object id)
        {
            T obj = default(T);

            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();
                    obj = (T)_session.Get<T>(id);
                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();
                _session.Clear();

                throw ex;
            }

            return obj;
        }

        public IEnumerable<T> Get(string fieldName, object fieldValue)
        {
            IEnumerable<T> list = null;

            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();
                    list = (IEnumerable<T>)_session.CreateCriteria(typeof(T))
                        .Add(new NHibernate.Expression.EqExpression(fieldName, fieldValue))
                        .List<T>();

                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();
                _session.Clear();

                throw ex;
            }

            return list;
        }

        public IEnumerable<T> Get()
        {
            IEnumerable<T> list = null;

            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();
                    list = (IEnumerable<T>)_session.CreateCriteria(typeof(T)).List<T>();
                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();
                _session.Clear();

                throw ex;
            }

            return list;
        }

        public void SaveOrUpdate(T obj)
        {
            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();
                    _session.SaveOrUpdateCopy(obj);
                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();
                _session.Clear();

                throw ex;
            }
        }

        public void SaveOrUpdate(IEnumerable<T> objs)
        {
            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();

                    foreach (T obj in objs)
                    {
                        _session.SaveOrUpdate(obj);
                    }

                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();
                _session.Clear();

                throw ex;
            }
        }

        public void Delete(T obj)
        {
            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();
                    _session.Delete(obj);
                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();                
                _session.Clear();

                throw ex;
            }
        }

        public void Delete(IEnumerable<T> objs)
        {
            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();

                    foreach (T obj in objs)
                    {
                        _session.Delete(obj);
                    }

                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();
                _session.Clear();

                throw ex;
            }
        }

        public void DeleteAll()
        {
            try
            {
                if (!_session.Transaction.IsActive)
                {
                    _session.BeginTransaction();

                    DetachedCriteria criterion = DetachedCriteria.For<T>();
                    IList<T> list = criterion.GetExecutableCriteria(_session).List<T>();

                    foreach (T item in list)
                    {
                        _session.Delete(item);
                    }

                    _session.Transaction.Commit();
                    _session.Flush();
                }
                else
                {
                    throw new Exception(CustomErrorMessage.TransactionAlreadyInProgress);
                }
            }
            catch (Exception ex)
            {
                _session.Transaction.Rollback();

                throw ex;
            }
        }

        public void Dispose()
        {
            if (_session != null)
            {
                _session.Clear();
                _session.Close();
                _session = null;
            }
        }
    }
public class SessionFactory
    {
        private static ISessionFactory _sessionFactory = null;
        private SessionFactory(){}

        static SessionFactory()
        {
            if (_sessionFactory == null)
            {
                Configuration configuration = new Configuration();
                configuration.Configure();
                _sessionFactory = configuration.BuildSessionFactory();
            }
        }

        public static ISession GetOpenSession()
        {
            return _sessionFactory.OpenSession();
        }
    }