Я начал работать над однопользовательским приложением C # winforms с первым подходом EF6 db, AutoMapper, Generic Repository и UnitOfWork. Ранее они были реализованы другими бывшими коллегами. Я не очень разбираюсь в этих концепциях, но прочитал много ссылок. Основная проблема теперь в том, что однопользовательское приложение C # необходимо обновить для работы в многопользовательской среде. При использовании текущей реализации внешние изменения (например, операции обновления), выполняемые в базе данных, не видны внутри контроллера.
Я пробовал использовать _unitOfWork.Context.Refresh (System.Data.Entity.Core.Objects.RefreshMode.StoreWins, _tableRepository.FindAllInContext ()); чтобы обновить контекст, но я думаю, что это не очень хороший вариант, потому что, если я попытаюсь обновить значение столбца таблицы после обновления, действие не будет сохранено в базе данных.
public interface IDbEntity
{
int Id { get; set; }
bool IsDeleted { get; set; }
}
public interface IRepository<T, T1>
where T : class, IDbEntity
where T1 : class, IDbEntity
{
int Add(T1 newEntityViewModel);
void AddRange(List<T1> newEntities);
void Remove(int id);
void RemoveFromDb(int id);
List<T1> Find(Expression<Func<T1, bool>> predicate);
T1 FindById(int id);
List<T1> FindAll();
T FindByIdInContext(int id);
int GetNextId();
List<T> FindAllInContext();
}
internal class DbRepository<T, T1> : IRepository<T, T1>
where T : class, IDbEntity
where T1 : class, IDbEntity
{
protected ObjectSet<T> _objectSet;
protected List<T1> _internalList;
protected ObjectContext _context;
public DbRepository(ObjectContext context)
{
try
{
_internalList = new List<T1>();
_objectSet = context.CreateObjectSet<T>();
_context = context;
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
public int Add(T1 newEntityViewModel)
{
try
{
var entityDto = AutoMapperConfiguration.GetMapperConfiguration().Map<T1, T>(newEntityViewModel);
_objectSet.AddObject(entityDto);
_context.SaveChanges();
//check id
return entityDto.Id;
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
public List<T1> Find(Expression<Func<T1, bool>> predicate)
{
try
{
var listT1 = AutoMapperConfiguration.GetMapperConfiguration().Map<List<T1>>(_objectSet.Where(q => !q.IsDeleted));
var result = listT1.Where(predicate.Compile()).ToList();
return result;
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
public List<T1> FindAll()
{
try
{
var listT1 = AutoMapperConfiguration.GetMapperConfiguration().Map<List<T1>>(_objectSet.Where(q => !q.IsDeleted));
return listT1;
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
}
public interface IUnitOfWork
{
IRepository<User, User_ViewModel> Users { get; }
IRepository<Type, Type_ViewModel> Types { get; }
/// and a lot more repositories
ObjectContext Context { get; }
void Commit();
}
internal class DbUnitOfWork : IUnitOfWork
{
private DbRepository<User, User_ViewModel> _users = null;
private DbRepository<Type, Type_ViewModel> _types = null;
private readonly ObjectContext _context;
private readonly EntityConnection _connectionString;
public ObjectContext Context { get { return _context; } }
public DbUnitOfWork(EntityConnection connectionString)
{
try
{
_connectionString = connectionString;
_context = new ObjectContext(connectionString, true);
_context.ContextOptions.LazyLoadingEnabled = true;
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
public IRepository<User, User_ViewModel> Users
{
get
{
return _users ?? (_users = new DbRepository<User, User_ViewModel>(_context));
}
}
public IRepository<Type, Type_ViewModel> Types
{
get
{
return _types ?? (_types = new DbRepository<Type, Type_ViewModel>(_context));
}
}
public void Commit()
{
try
{
_context.SaveChanges();
}
catch (Exception ex)
{
log.Error(ex.Message);
throw;
}
}
}
DbController.cs
public partial class DbController
{
protected readonly IUnitOfWork _unitOfWork;
protected readonly IRepository<User, User_ViewModel> _userRepository;
protected readonly IRepository<Type, Type_ViewModel> _typeRepository;
public SafeIOController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_userRepository = _unitOfWork.Users;
_typeRepository = _unitOfWork.Types;
}
public void Save()
{
_unitOfWork.Commit();
}
}
Controller_User.cs
public partial class DbController
{
public List<User_ViewModel> GetAllUsers()
{
try
{
return _userRepository.FindAll();
}
catch (Exception ex)
{
_exHandler.LogErrorMessage(Constants_Exception.DB_EXCEPTION_MSG, ex, _exHandler.GetCurrentMethod());
throw;
}
}
}
and then in winforms app
_unitOfWork = new DbUnitOfWork(connectionString);
_controller = new DbController(_unitOfWork);
Как я могу правильно реализовать unitOfWork, чтобы иметь самую свежую информацию из db в моем контексте?