UnitOfWorkを使用してデータを保存する際に問題が発生しています。ControllerクラスのUnitOFWork.Commit()を使用してデータを保存できないことを意味します。以下の私の実装チェック。
IUnitOfWork
public interface IUnitOfWork<C> : IDisposable
{
int Commit();
C GetContext { get; set; }
TransactionScope BeginTransaction();
}
UnitOfWork
public class UnitOfWork<C> : IUnitOfWork<C> where C : DbContext
{
private bool _disposed;
private readonly C _dbContext = null;
private TransactionScope _transaction;
public UnitOfWork()
{
GetContext = _dbContext ?? Activator.CreateInstance<C>();
}
public int Commit()
{
return GetContext.SaveChanges();
}
public C GetContext
{
get;
set;
}
public TransactionScope BeginTransaction()
{
if (null != _transaction)
{
_transaction = new TransactionScope();
}
return _transaction;
}
#region IDisposable Members
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (null != _transaction)
{
_transaction.Dispose();
}
if (null != _dbContext)
{
_dbContext.Dispose();
}
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
現在、 RepositoryBase/GenericRepository内にあります
public abstract class RepositoryBase<C, E> : IRepository<E> where E : class where C : DbContext
{
private readonly IDbSet<E> _dbSet;
protected RepositoryBase(IUnitOfWork<C> unitOfWork)
{
UnitOfWork = unitOfWork;
_dbSet = UnitOfWork.GetContext.Set<E>();
}
protected IUnitOfWork<C> UnitOfWork
{
get;
private set;
}
#region IRepository<E> Members
public void Insert(E entity)
{
_dbSet.Add(entity);
UnitOfWork.GetContext.Entry(entity).State = System.Data.EntityState.Added;
UnitOfWork.Commit();
}
[...]
UnitOfWork.Commit();を使用する場合 GenericRepository内でデータを正常に保存できます。しかし、UnitOfWork.Commit();を使用すると コントローラがないのでデータを保存できません。
コントローラコード
private readonly IEmployeeRepository _employeeRepository;
public EmployeeController(IEmployeeRepository employeeRepositoty, IUnitOfWork<MyDbContext> unitOfWork)
{
UnitOfWork = unitOfWork;
this._employeeRepository = employeeRepositoty;
}
[HttpPost]
public ActionResult Create(EmployeeModel employeemodel)
{
if (ModelState.IsValid)
{
using (UnitOfWork)
{
_employeeRepository.Insert(employeemodel);
UnitOfWork.Commit(); //OR UnitOfWork.GetContext.SaveChanges();
}
return RedirectToAction("Index");
}
return View(employeemodel);
}
Controller内でUnitOfWork.commit()を使用する場合、 GenericRepositoryInsertメソッドコードを以下で確認します
public void Insert(E entity)
{
_dbSet.Add(entity);
UnitOfWork.GetContext.Entry(entity).State = System.Data.EntityState.Added;
}
私の理解によると、これはUnitOfWorkの設計上の問題です。それを解決するのを手伝ってください。
IEmployeeRepository
public interface IEmployeeRepository : IRepository<EmployeeModel>
{
}
public class EmployeeRepository : RepositoryBase<MyDbContext, EmployeeModel>, IEmployeeRepository
{
public EmployeeRepository(IUnitOfWork<MyDbMContext> unitOfWork)
: base(unitOfWork)
{
}
}
NinjetDIConfiguration
kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>();
kernel.Bind<ICountryRepository>().To<CountryRepository>();
kernel.Bind<IUserProfileRepository>().To<UserProfileRepository>();
kernel.Bind<IEmployeeRepository>().To<EmployeeRepository>();