与多的DbContext工作模式库和单位的最佳实践 [英] Best Practice of Repository and Unit of Work Pattern with Multiple DbContext

查看:637
本文介绍了与多的DbContext工作模式库和单位的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划开发使用ASP.NET MVC实体框架6(code首先/ POCO)的Web应用程序。我也想用通用的存储库和工作模式在单位我的应用程序。这个应用程序连接到两个以上的数据库,这样,我在应用程序中使用多个的DbContext。

I plan to develop a web application using ASP.NET MVC with Entity Framework 6 (Code First / POCO). I also want to use generic Repository and Unit of Work Pattern in my application. This application connects to more than two databases so, I have to use multiple DbContext in the application.

public class ContextOne : DbContext
{
    public DbSet<Model_One1>
    public DbSet<Model_One2>
}

public class ContextTwo : DbContext
{
    public DbSet<Model_Two1>
    public DbSet<Model_Two2>
}

public class ContextThree : DbContext
{
    public DbSet<Model_Three1>
    public DbSet<Model_Three2>
}

public interface IRepository<T> where T : DbContext
{
    void Add<T>(T entity) where T : class;
}

public class Repository<T> where T : DbContext
{
    void Add<T>(T entity) where T : class
    {
        //T is DbContext and Model. So confusing
    }
}

public interface IUnitOfWork<IRepository>
{
}

public class UnitOfWork<IRepository>
{
    //IRepository contains more than one DbContext how can I initiate them here?
}

//in application should look like this
public class BaseController : Controller
{
    protected IRepository repository = new .. //here I have no idea with multiple DbContext
}

public class HomeController : BaseController
{
    public ActionResult Add(Model_Two2 model)
    {
        base.repository.Add<Model_Two2>(model)
    }
}

如果我把从控制器的IRepository和IUnitOfWork我怎么能知道匹配的情况下?这是什么问题的最佳实践?

If I call the IRepository and IUnitOfWork from Controller how can I know the matching context? What's the best practice of this problem?

推荐答案

我建议你用一个参数的构造函数创建的UnitOfWork模式接受的DbContext -

I would suggest you to create UnitOfWork pattern with a Constructor parameter to accept DbContext -

public class UnitOfWork : IUnitOfWork
{
    private readonly IDbContext _context;

    private bool _disposed;
    private Hashtable _repositories;

    public UnitOfWork(IDbContext context)
    {
        _context = context;
    }

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

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

    public virtual void Dispose(bool disposing)
    {
        if (!_disposed)
            if (disposing)
                _context.Dispose();

        _disposed = true;
    }

    public IRepository<TEntity> Repository<TEntity>() where TEntity : class
    {
        if (_repositories == null)
            _repositories = new Hashtable();

        var type = typeof(TEntity).Name;

        if (_repositories.ContainsKey(type)) return (IRepository<TEntity>) _repositories[type];

        var repositoryType = typeof (Repository<>);

        var repositoryInstance =
            Activator.CreateInstance(repositoryType
                .MakeGenericType(typeof (TEntity)), _context);

        _repositories.Add(type, repositoryInstance);

        return (IRepository<TEntity>) _repositories[type];
    }
}

其中IDbContext是 -

where IDbContext is -

public interface IDbContext
{
    IDbSet<T> Set<T>() where T : class;
    int SaveChanges();
    void Dispose();
}

和存储库的实现将是 -

And the repository implementation would be -

 public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        internal IDbContext Context;
        internal IDbSet<TEntity> DbSet;

        public Repository(IDbContext context)
        {
            Context = context;
            DbSet = context.Set<TEntity>();
        }

        public virtual TEntity FindById(object id)
        {
            return DbSet.Find(id);
        }

        public virtual void Update(TEntity entity)
        {
            DbSet.Attach(entity);
        }
        public virtual void Delete(object id)
        {
            var entity = DbSet.Find(id);
            var objectState = entity as IObjectState;
            if (objectState != null)
                objectState.State = ObjectState.Deleted;
            Delete(entity);
        }

        public virtual void Delete(TEntity entity)
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }

        public virtual void Insert(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual List<TEntity> GetAll()
        {
            return DbSet.ToList();
        }
    }

通过这种方法,您可以为个人的DbContext创建的UnitOfWork并有特定的逻辑来提交或回滚中的UnitOfWork。

With this approach you can create a UnitOfWork for individual DBContext and you have specific logic to commit or rollback in UnitOfWork.

这篇关于与多的DbContext工作模式库和单位的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆