我在我的应用程序中使用 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();
}
}