c# - Entity Framework 6、存储库模式和工作单元

标签 c# entity-framework design-patterns repository-pattern

我正在学习 Entity Framework 和一些设计模式,例如存储库模式和工作单元。我编写了一个使用这些模式的程序。在这个类中,我有一个 DbContext 对象,并且我总是使用这个静态 DbContext。在我的应用程序的整个生命周期中,只有一个 DbContext 对象。我用这种方式做得对吗,想想如果有很多用户。会出现有关数据库连接的任何问题。

用户界面代码:

UnitOfWork uow = GetUnitOfWork(); //There is only one uow object
uow.EmployeeRepository.Insert(new Employee
{
    Name = name,
    Surname = surname
});

获取UnitOfWork代码:

private static UnitOfWork _uow;
public static UnitOfWork GetUnitOfWork()
{
    return _uow ?? (_uow = new 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);
    }
}

最佳答案

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 和存储库都不是抽象的(带有接口(interface))。这意味着客户端仍然耦合到唯一的实现。您刚刚创建了一个封装的 Entity Framework ,但您无法从中受益,例如,您无法在不重写它的情况下切换到另一个实现。除了锻炼之外,我没有看到任何实质性的意义。

关于c# - Entity Framework 6、存储库模式和工作单元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26980295/

相关文章:

java - 从字符串初始化子类对象

oop - 在一个好的 OOP 设计中,我们应该使用什么来代替 "manager"类?

c# - 为什么 DefaultIfEmpty 是这样实现的?

c# - 内部构造器

linq - 包括使用 Lambda 表达式

c# - Entity Framework 与直接数据访问

c# - 如何使 M :N (many-to-many) relationship where both M and N are the same entities?

java - 创建具有不同参数的类的多个实例

c# - EWS 托管 API : how to set From of email?

c# - 仅在自上次使用后 X 秒后执行方法