为什么DbContext没有实现IDbContext接口?

Gri*_*der 52 testing unit-testing entity-framework moq mocking

为什么IDbContext实体框架中没有接口?如果现有的接口有类似SaveChanges()等的方法来测试,那么你可以从中导出自定义数据库上下文接口吗?

public interface ICustomDbContext : IDbContext
{
    // add entity set properties to existing set of methods in IDbContext
    IDbSet<SomeEntity> SomeEntities { get; }
}
Run Code Online (Sandbox Code Playgroud)

use*_*116 14

我看到了这个IDbContext:

查看此链接然后为您的Entities Context With That接口创建一个新的分部类.

public partial class YourModelEntities : DbContext, IDbContext 
Run Code Online (Sandbox Code Playgroud)

编辑:我编辑了这篇文章,这对我有用.我的背景

namespace dao
{
    public interface ContextI : IDisposable
    {
        DbSet<TEntity> Set<TEntity>() where TEntity : class;
        DbSet Set(Type entityType);
        int SaveChanges();
        IEnumerable<DbEntityValidationResult> GetValidationErrors();
        DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity:class;
        DbEntityEntry Entry(object entity);
        string ConnectionString { get; set; }
        bool AutoDetectChangedEnabled { get; set; }
        void ExecuteSqlCommand(string p, params object[] o);
        void ExecuteSqlCommand(string p);
    }
}
Run Code Online (Sandbox Code Playgroud)

YourModelEntities是您自动生成的分部类,您需要创建一个具有相同名称的新分部类,然后添加新的上下文接口,对于此示例是ContextI

注意:接口尚未实现所有方法,因为这些方法是在自动生成代码中实现的.

namespace dao
{
    public partial class YourModelEntities :DbContext, ContextI
    {
        public string ConnectionString
        {
            get
            {
                return this.Database.Connection.ConnectionString;
            }
            set
            {
                this.Database.Connection.ConnectionString = value;
            }
        }

        bool AutoDetectChangedEnabled
        {
            get
            {
                return true;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void ExecuteSqlCommand(string p,params object[] os)
        {
            this.Database.ExecuteSqlCommand(p, os);
        }

        public void ExecuteSqlCommand(string p)
        {
            this.Database.ExecuteSqlCommand(p);
        }

        bool ContextI.AutoDetectChangedEnabled
        {
            get
            {
                return this.Configuration.AutoDetectChangesEnabled;
            }
            set
            {
                this.Configuration.AutoDetectChangesEnabled = value;
            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)


Swe*_*ell -13

没有 IDbContext 因为它没有用,它的唯一实现就是 DbContext。

如果您查看此设计会议记录,EF 团队也会采用 IDbSet 的方式

对我来说,EF 在单元测试方面的真正问题是 DbContext 中的 DbConnection,幸运的是 Codeplex 上有一个不错的项目Effort开始填补这个问题。

Effort 是一个功能强大的工具,可以方便地为基于实体框架的应用程序创建自动化测试。它基本上是一个 ADO.NET 提供程序,在轻量级进程内主内存数据库而不是传统的外部数据库上执行所有数据操作。它还提供了一些直观的帮助器方法,使该提供程序与现有的 ObjectContext 或 DbContext 类一起使用变得非常容易。对现有代码的简单添加可能足以创建可以在不存在外部数据库的情况下运行的数据驱动测试。

这样,您可以按原样保留 DbContext 和 DbSet 并轻松进行单元测试。唯一的缺点是 Linq 提供商之间的差异,其中一些单元测试可能会通过努力而不是真正的后端通过。

使用 EF7 更新

我仍然认为 IDbContext 毫无用处,问题来自于 DbConnection。

EF7 也不会有 IDbContext,为了进行单元测试,他们现在提供了一个内存提供程序。

您可以看到 Rowan Miller 在此处进行演示:使用 Entity Framework 7 的现代数据应用程序

  • IDbContext肯定不会毫无用处。由于它是存储库模式实现的主要组件之一,如果我们不能注入模拟上下文而不是实际实现的上下文,则单元测试是不可能的。即使我们不能使用 Repository 模式,这个问题仍然有效。所有 DAL 层的主要组件都是上下文,并且必须是可模拟的。当然,如果可以使用一些技巧和代码生成器等来模拟,但是模拟它的通用和通用方法始终基于模拟组件正在实现的接口。自从 _years_ 以来,EF 设计者就完全忽略了这一点 (4认同)
  • 这根本就没有什么用处。现在我们正在使用依赖于 DBContext 实例的 WCF 数据服务。如果它依赖于接口,我们将能够访问 Set&lt;T&gt;() 方法调用并提供我们迫切需要的过滤层(查询拦截器根本不够)。 (3认同)
  • 您应该阅读此http://msdn.microsoft.com/en-US/data/dn314429。您将看到没有实际界面的模拟。 (2认同)