Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在工作单元/存储库模式中处理上下文_C#_Entity Framework_Design Patterns - Fatal编程技术网

C# 在工作单元/存储库模式中处理上下文

C# 在工作单元/存储库模式中处理上下文,c#,entity-framework,design-patterns,C#,Entity Framework,Design Patterns,您好,我在应用程序中实现了UoW/Repository模式,特别是遵循MSDN教程。然而,当涉及到处理上下文时,我感到困惑(不可否认,这是因为我还有很多关于C#中内存管理的知识需要学习) 无论如何,我有一个上下文,它被传递给: 工作单位 通用存储库 特定存储库 我的问题:我应该在什么时候处理该上下文,我拥有的哪些接口应该从IDisposable派生/哪些类应该实现IDisposable 目前,我从IGenericRepository和IUnitOfWork中的IDisposable派生,然后

您好,我在应用程序中实现了UoW/Repository模式,特别是遵循MSDN教程。然而,当涉及到处理上下文时,我感到困惑(不可否认,这是因为我还有很多关于C#中内存管理的知识需要学习)

无论如何,我有一个上下文,它被传递给:

  • 工作单位
  • 通用存储库
  • 特定存储库
我的问题:我应该在什么时候处理该上下文,我拥有的哪些接口应该从IDisposable派生/哪些类应该实现IDisposable

目前,我从IGenericRepository和IUnitOfWork中的IDisposable派生,然后在GenericRepository和UnitOfWork中实现Dispose方法。但是在MSDN教程中,Dispose方法的实现是在特定的存储库中,而不是在通用存储库中,这是我感到困惑的原因。如果我使用相同的上下文实例从基类(通用存储库)传递到使用基本构造函数获取上下文的特定存储库,那么如果我在通用存储库中处理它,这还不够吗

接口:

public interface IUnitOfWork : IDisposable
{
    IAccountsRepository Accounts { get; }
    ITransactionsRepository Transactions { get; }
    IAccountGroupsRepository AccountGroups { get; }

    void Complete();
}

public interface IGenericRepository<TEntity> : IDisposable where TEntity : class
{
    void Add(TEntity entity);
    void Edit(TEntity entity);
    IEnumerable<TEntity> GetAll();
    TEntity GetById(object id);
    void Remove(object id);
    void Remove(TEntity entity);
}

public interface IAccountsRepository : IGenericRepository<Account>
{
    IEnumerable<Account> GetForUser(string applicationUserId);
    string GetAccountName(int accountId);
}
public class UnitOfWork : IUnitOfWork
{
    private readonly TinyBooksDbContext _context;
    private bool _disposed;

    public IAccountsRepository Accounts { get; }
    public ITransactionsRepository Transactions { get; }
    public IAccountGroupsRepository AccountGroups { get; set; }


    public UnitOfWork(TinyBooksDbContext context)
    {
        _context = context;
        Accounts = new AccountsRepository(_context);
        Transactions = new TransactionsRepository(_context);
        AccountGroups = new AccountGroupsRepository(_context);
    }

    public void Complete()
    {
        _context.SaveChanges();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    private readonly TinyBooksDbContext _context;
    private readonly DbSet<TEntity> _dbSet;
    private bool _disposed;

    public GenericRepository(TinyBooksDbContext context)
    {
        _context = context;
        _dbSet = _context.Set<TEntity>();

    }

    // C
    public virtual void Add(TEntity entity)
    {
        _dbSet.Add(entity);
    }

    public virtual IEnumerable<TEntity> GetAll()
    {
        return _dbSet.ToList();
    }

    // R
    public virtual TEntity GetById(object id)
    {
        return _dbSet.Find(id);
    }

    // U
    public virtual void Edit(TEntity entity)
    {
        _dbSet.Attach(entity);
        _context.Entry(entity).CurrentValues.SetValues(entity);
    }


    // D
    public virtual void Remove(object id)
    {
        var entity = _dbSet.Find(id);
        Remove(entity);
    }

    public virtual void Remove(TEntity entity)
    {
        if (_context.Entry(entity).State == EntityState.Detached)
            _dbSet.Attach(entity);

        _dbSet.Remove(entity);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public class AccountsRepository : GenericRepository<Account>, IAccountsRepository
{
    private readonly TinyBooksDbContext _context;
    private bool _disposed;

    public AccountsRepository(TinyBooksDbContext context) : base(context)
    {
        _context = context;
    }

    public IEnumerable<Account> GetForUser(string applicationUserId) =>
        _context.Accounts.Where(a => a.ApplicationUserId == applicationUserId).ToList();

    public string GetAccountName(int accountId) =>
        _context.Accounts.SingleOrDefault(a => a.Id == accountId).Name;
}
公共接口IUnitOfWork:IDisposable
{
IAccountsRepository帐户{get;}
ITransactionsRepository事务{get;}
IAccountGroupsRepository AccountGroups{get;}
完全无效();
}
公共接口IGenericRepository:IDisposable where tenty:class
{
无效添加(潜在实体);
无效编辑(TEntity实体);
IEnumerable GetAll();
TEntity GetById(对象id);
无效删除(对象id);
无效删除(潜在实体);
}
公共接口IAccountsRepository:IGenericRepository
{
IEnumerable GetForUser(字符串应用程序序列号);
字符串GetAccountName(int accountId);
}
实施:

public interface IUnitOfWork : IDisposable
{
    IAccountsRepository Accounts { get; }
    ITransactionsRepository Transactions { get; }
    IAccountGroupsRepository AccountGroups { get; }

    void Complete();
}

public interface IGenericRepository<TEntity> : IDisposable where TEntity : class
{
    void Add(TEntity entity);
    void Edit(TEntity entity);
    IEnumerable<TEntity> GetAll();
    TEntity GetById(object id);
    void Remove(object id);
    void Remove(TEntity entity);
}

public interface IAccountsRepository : IGenericRepository<Account>
{
    IEnumerable<Account> GetForUser(string applicationUserId);
    string GetAccountName(int accountId);
}
public class UnitOfWork : IUnitOfWork
{
    private readonly TinyBooksDbContext _context;
    private bool _disposed;

    public IAccountsRepository Accounts { get; }
    public ITransactionsRepository Transactions { get; }
    public IAccountGroupsRepository AccountGroups { get; set; }


    public UnitOfWork(TinyBooksDbContext context)
    {
        _context = context;
        Accounts = new AccountsRepository(_context);
        Transactions = new TransactionsRepository(_context);
        AccountGroups = new AccountGroupsRepository(_context);
    }

    public void Complete()
    {
        _context.SaveChanges();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    private readonly TinyBooksDbContext _context;
    private readonly DbSet<TEntity> _dbSet;
    private bool _disposed;

    public GenericRepository(TinyBooksDbContext context)
    {
        _context = context;
        _dbSet = _context.Set<TEntity>();

    }

    // C
    public virtual void Add(TEntity entity)
    {
        _dbSet.Add(entity);
    }

    public virtual IEnumerable<TEntity> GetAll()
    {
        return _dbSet.ToList();
    }

    // R
    public virtual TEntity GetById(object id)
    {
        return _dbSet.Find(id);
    }

    // U
    public virtual void Edit(TEntity entity)
    {
        _dbSet.Attach(entity);
        _context.Entry(entity).CurrentValues.SetValues(entity);
    }


    // D
    public virtual void Remove(object id)
    {
        var entity = _dbSet.Find(id);
        Remove(entity);
    }

    public virtual void Remove(TEntity entity)
    {
        if (_context.Entry(entity).State == EntityState.Detached)
            _dbSet.Attach(entity);

        _dbSet.Remove(entity);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public class AccountsRepository : GenericRepository<Account>, IAccountsRepository
{
    private readonly TinyBooksDbContext _context;
    private bool _disposed;

    public AccountsRepository(TinyBooksDbContext context) : base(context)
    {
        _context = context;
    }

    public IEnumerable<Account> GetForUser(string applicationUserId) =>
        _context.Accounts.Where(a => a.ApplicationUserId == applicationUserId).ToList();

    public string GetAccountName(int accountId) =>
        _context.Accounts.SingleOrDefault(a => a.Id == accountId).Name;
}
公共类UnitOfWork:IUnitOfWork
{
私有只读TinyBooksDbContext\u上下文;
私人住宅;
公共IAccountsRepository帐户{get;}
公共ITransactionsRepository事务{get;}
公共IACCountGroups存储帐户组{get;set;}
公共UnitOfWork(TinyBooksDbContext上下文)
{
_上下文=上下文;
Accounts=新AccountsRepository(\u上下文);
事务=新事务存储库(_上下文);
AccountGroups=新AccountGroupsRepository(\u上下文);
}
公开作废完成()
{
_SaveChanges();
}
受保护的虚拟void Dispose(bool disposing)
{
如果(!\u已处置)
{
如果(处置)
{
_context.Dispose();
}
}
_这是真的;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
}
公共类GenericRepository:IGenericRepository,其中tenty:class
{
私有只读TinyBooksDbContext\u上下文;
私有只读数据库集_DbSet;
私人住宅;
公共GenericRepository(TinyBooksDbContext上下文)
{
_上下文=上下文;
_dbSet=_context.Set();
}
//C
公共虚拟空添加(TEntity实体)
{
_添加(实体);
}
公共虚拟IEnumerable GetAll()
{
return_dbSet.ToList();
}
//R
公共虚拟实体GetById(对象id)
{
返回_dbSet.Find(id);
}
//U
公共虚拟无效编辑(TEntity实体)
{
_附加数据集(实体);
_context.Entry(实体).CurrentValues.SetValues(实体);
}
//D
公共虚拟无效删除(对象id)
{
var entity=_dbSet.Find(id);
删除(实体);
}
公共虚拟无效删除(TEntity实体)
{
if(_context.Entry(entity.State==EntityState.Detached)
_附加数据集(实体);
_删除(实体);
}
受保护的虚拟void Dispose(bool disposing)
{
如果(!\u已处置)
{
如果(处置)
{
_context.Dispose();
}
}
_这是真的;
}
公共空间处置()
{
处置(真实);
总干事(本);
}
}
公共类AccountsRepository:GenericRepository、IAccountsRepository
{
私有只读TinyBooksDbContext\u上下文;
私人住宅;
公共帐户存储(TinyBooksDbContext上下文):基础(上下文)
{
_上下文=上下文;
}
public IEnumerable GetForUser(字符串applicationSerID)=>
_context.Accounts.Where(a=>a.applicationSerid==applicationSerid.ToList();
公共字符串GetAccountName(int accountId)=>
_context.Accounts.SingleOrDefault(a=>a.Id==accountId).Name;
}

一般来说,上下文的创建者应该处理它

不要在传递上下文的类中处理上下文,因为这会混淆其他开发人员,他们可能会在处理上下文后使用它


在您的示例中,回购协议不应处置上下文-它们不拥有上下文

一般来说,上下文的创建者应该处理它

不要在传递上下文的类中处理上下文,因为这会混淆其他开发人员,他们可能会在处理上下文后使用它


在您的示例中,回购协议不应处置上下文-它们不拥有上下文

您可以在UnitOfWork类中声明上下文期间初始化上下文,其生存期将取决于UnitOfWork类的生存期

public class UnitOfWork : IDisposable, IUnitOfWork
{
    private readonly TinyBooksDbContext context = new TinyBooksDbContext();

    ......

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

这样,您的上下文将与您的UoW实例一起处理。您不应该在泛型存储库中有dispose方法。

您可以在UnitOfWork类中声明上下文时初始化上下文,其生存期将取决于UnitOfWork类的生存期

public class UnitOfWork : IDisposable, IUnitOfWork
{
    private readonly TinyBooksDbContext context = new TinyBooksDbContext();

    ......

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
这样,您的上下文将与您的UoW实例一起处理。你不应该把它弄坏