2

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

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

部门收集表格

部门实体表格

但是当一个表单从另一个表单中被 ShowDialog()ged 时,就会出现问题。

当我在做任何与数据库相关的操作时,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);
        }

A Save 像这样工作,

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

public class FacultyRepository : Repository<Faculty>
    {
    }

DepartmentRepository.cs

public class DepartmentRepository : Repository<Department>
    {
    }

存储库.cs

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;
            }
        }
    }

会话工厂.cs

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();
        }
    }
4

1 回答 1

2

好了朋友们!自从我发布我的问题以来已经很久了,没有人愿意回答它。

我通过ISession staticSessionFactoryand 而不是为每个存储库返回一个 Open来解决它ISession,我只返回一个static ISession.

于 2010-11-13T04:31:29.557 回答