首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >工作单位和具有实体框架5的通用知识库

工作单位和具有实体框架5的通用知识库
EN

Stack Overflow用户
提问于 2013-05-23 14:24:56
回答 2查看 28.9K关注 0票数 28

我在实体框架5中使用了ASP.NET MVC 4,我有模型类和实体地图来将现有表映射到这些模型类。所有这些都是很好的设置和工作的伟大。

现在我想嘲笑这个。我创建了工作单元( Unit Of Work ),它采用了DataContext,并使用了一个通用存储库。在此基础上,我构建了能够同时从多个存储库获取数据的服务,并且只需要拥有DataContext的一个实例。这也很好用。

现在的问题是:我想用模拟数据来测试服务。当我创建工作单元实例时,我希望能够插入一个被模拟的DataContext,而不是真正的DataContext。

我试图创建一个IContext接口,让真正的和模拟的DataContext实现它,但是DbSet遇到了问题。我试图使用IDbSet并创建一个FakeDbSet,但没有成功。我还在互联网上读到,用IDbSet来嘲弄上下文并使用FakeDbSet是一种糟糕的方法。

你知道什么是实现这一目标的最佳方式吗?我现在拥有的是我想要保持的行为,但我真的希望能够模拟来自DataContext中的Model类的数据。

我知道实体框架已经提供了工作行为单元,您不需要在此基础上添加额外的行为。但是我想把它封装在另一个类中,它跟踪所有的存储库(称为UnitOfWork类)。

编辑:--我写了两篇文章,解释了我使用LINQ和实体框架的解决方案。

http://gaui.is/how-to-mock-the-datacontext-linq/

http://gaui.is/how-to-mock-the-datacontext-entity-framework/

这是我的密码:

IRepository.cs

代码语言:javascript
复制
public interface IRepository<T> where T : class
{
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    T GetById(long Id);
    IEnumerable<T> All();
    IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
}

IUnitOfWork.cs

代码语言:javascript
复制
public interface IUnitOfWork : IDisposable
{
    IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
    void Save();
}

Repository.cs

代码语言:javascript
复制
public class Repository<T> : IRepository<T> where T : class
{
    private readonly IDbContext _context;
    private readonly IDbSet<T> _dbset;

    public Repository(IDbContext context)
    {
        _context = context;
        _dbset = context.Set<T>();
    }

    public virtual void Add(T entity)
    {
        _dbset.Add(entity);
    }

    public virtual void Delete(T entity)
    {
        var entry = _context.Entry(entity);
        entry.State = System.Data.EntityState.Deleted;
    }

    public virtual void Update(T entity)
    {
        var entry = _context.Entry(entity);
        _dbset.Attach(entity);
        entry.State = System.Data.EntityState.Modified;
    }

    public virtual T GetById(long id)
    {
        return _dbset.Find(id);
    }

    public virtual IEnumerable<T> All()
    {
        return _dbset;
    }

    public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
    {
        return _dbset.Where(predicate);
    }
}

UnitOfWork.cs

代码语言:javascript
复制
public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
    private readonly IDbContext _ctx;
    private Dictionary<Type, object> _repositories;
    private bool _disposed;

    public UnitOfWork()
    {
        _ctx = new TContext();
        _repositories = new Dictionary<Type, object>();
        _disposed = false;
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
    {
        if (_repositories.Keys.Contains(typeof(TEntity)))
            return _repositories[typeof(TEntity)] as IRepository<TEntity>;

        var repository = new Repository<TEntity>(_ctx);
        _repositories.Add(typeof(TEntity), repository);
        return repository;
    }

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

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

    protected virtual void Dispose(bool disposing)
    {
        if (!this._disposed)
        {
            if (disposing)
            {
                _ctx.Dispose();
            }

            this._disposed = true;
        }
    }
}

ExampleService.cs

代码语言:javascript
复制
public class ExampleService
{
    private IRepository<Example> m_repo;

    public ExampleService(IUnitOfWork uow)
    {
        m_repo = uow.GetRepository<Example>();
    }

    public void Add(Example Example)
    {
        m_repo.Add(Example);
    }

    public IEnumerable<Example> getAll()
    {
        return m_repo.All();
    }
}

ExampleController.cs

代码语言:javascript
复制
public IEnumerable<Example> GetAll()
{
    // Create Unit Of Work object
    IUnitOfWork uow = new UnitOfWork<AppDataContext>();

    // Create Service with Unit Of Work attached to the DataContext
    ExampleService service = new ExampleService(uow);

    return service.getAll();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-23 14:58:14

您的ExampleService类需要IUnitOfWork,这意味着您只需要另一个IUnitOfWork,即Mock,其GetRepository()方法将返回IRepository Mock。

例如(不是真正的模拟存根,而是内存存根):

代码语言:javascript
复制
  public InMemoryRepository<T> : IRepository<T> where T : class
  {
        ........
  }

  public InMemoryUnitOfWork : IUnitOfWork
  {
       public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
       {
            return new InMemoryRepository<TEntity>();
       }
  }

然后:

代码语言:javascript
复制
public IEnumerable<Example> GetAll()
{
    // Create Unit Of Work object
    IUnitOfWork uow = new InMemoryUnitOfWork();

    // Create Service with Unit Of Work
    ExampleService service = new ExampleService(uow);

    return service.getAll();
}
票数 10
EN

Stack Overflow用户

发布于 2013-12-28 01:05:15

您可以遵循以下链接,这是非常有用的。

实体框架MVC3应用中的通用存储模式

实体框架和数据模式

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16716527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档