Я использую шаблоны NHibernate и Repository в своем приложении.Но я не хочу использовать шаблон UnitofWork.
В моем приложении есть два типа форм.Формы сбора / выбора и формы сущностей.
![Dept Collection Form](https://i.stack.imgur.com/yCwlQ.png)
![Dept Entity Form](https://i.stack.imgur.com/zdUJC.png)
Но проблема возникает, когда форма вызывается ShowDialog () из другой формы.
Несмотря на то, что я выполняю любую операцию, связанную с базой данных, NHibernate дает мне сообщение об ошибке «другой объект с таким же значением идентификатора уже был связан с сеансом: XYZ».Это вызвано задержкой вызова метода Dispose из CLR, и, насколько я понимаю, другая часть моей проблемы связана с управлением сеансом.
Как изменить коды репозитория для решения моей проблемы?
Помните, я не хочу показывать отдельные функции, подобные 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 Сохранение работает следующим образом,
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>
{
}
Repository.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;
}
}
}
SessionFactory.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();
}
}