我正在学习实体框架和一些设计模式,例如存储库模式和工作单元。我写了一个使用这些模式的程序。在这个类中,我有一个DbContext对象,我总是使用这个静态DbContext。在我的应用程序的整个生命周期中,只有一个DbContext对象。我是否正确地使用这种方式,想想是否有很多用户。将是有关数据库连接的任何问题。
UI代码:
UnitOfWork uow = GetUnitOfWork(); //There is only one uow object
uow.EmployeeRepository.Insert(new Employee
{
Name = name,
Surname = surname
});
GetUnitOfWork代码:
private static UnitOfWork _uow;
public static UnitOfWork GetUnitOfWork()
{
return _uow ?? (_uow = new UnitOfWork());
}
UnitOfWork代码:
public class UnitOfWork : IDisposable
{
private static FollowerEntities _context;
private DbContextTransaction _transaction;
//repositories
private EmployeeRepository _employeeRepository;
public UnitOfWork()
{
_context = new FollowerEntities();
}
public EmployeeRepository EmployeeRepository
{
get { return _employeeRepository ?? (_employeeRepository = new EmployeeRepository(_context)); }
}
public void Save()
{
try
{
_transaction = _context.Database.BeginTransaction();
_context.SaveChanges();
_transaction.Commit();
}
catch
{
_transaction.Rollback();
throw;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}
员工存储库
public class EmployeeRepository : GenericRepository<Employee>
{
public EmployeeRepository(FollowerEntities entities)
: base(entities)
{
}
}
通用存储库
public class GenericRepository<T> where T : class
{
private FollowerEntities _entities;
private DbSet<T> table = null;
public GenericRepository()
{
}
public GenericRepository(FollowerEntities entities)
{
this._entities = entities;
table = _entities.Set<T>();
}
public IEnumerable<T> SelectAll()
{
return table.ToList();
}
public T SelvectById(object id)
{
return table.Find(id);
}
public void Insert(T obj)
{
table.Add(obj);
}
public void Update(T obj)
{
table.Attach(obj);
_entities.Entry(obj).State = EntityState.Modified;
}
public void Delete(object id)
{
T existing = table.Find(id);
table.Remove(existing);
}
}
答案 0 :(得分:4)
private static UnitOfWork _uow;
public static UnitOfWork GetUnitOfWork()
{
return _uow ?? (_uow = new UnitOfWork());
}
虽然技术上是正确的,但这并不像你想象的那样有用。您将API限制为UoW的单个实例。考虑像ASP.NET这样的共享场景,这种方法可能不会像您想象的那样频繁使用。我建议删除它。
public UnitOfWork()
{
_context = new FollowerEntities();
}
这会不必要地将上下文生命周期与UoW生命周期联系起来。相反,将它们分开:
public UnitOfWork( FollowerEntities context )
{
_context = context;
}
这样,可以使用其他生命周期管理方法(可能是IoC容器)。
_transaction = _context.Database.BeginTransaction();
_context.SaveChanges();
_transaction.Commit();
您确定应该始终将保存包装在交易中吗?如果同一连接上存在另一个事务并且您想重用它,该怎么办?
最大的问题 - UoW和存储库都不是抽象的(带接口)。这意味着客户端仍然与唯一的实现耦合。您刚刚创建了一个包装的实体框架,但您无法从中受益,例如,您无法在不重写的情况下切换到另一个实现。除了锻炼之外,我没有看到任何坚实的观点。