【问题标题】:UnintentionalCodeFirstException | Entity Framework Unit Testing with Effort.Ef6 using Database FirstUnintentionalCodeFirstException |使用 Effort.Ef6 使用 Database First 进行实体框架单元测试
【发布时间】:2017-09-12 08:57:54
【问题描述】:

情况

我想基于实体框架 6 启用我的 DbContext 的单元测试。我已经使用数据库优先方法创建了我的 DbContext 和我的模型,现在有一个 .edmx 设计器文件.

问题

我自动创建的DbContext 确实会覆盖DbContext.OnModelCreating 方法,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

我正在尝试根据this article 的信息在我的模拟数据访问服务中创建我的DbContext 的新实例。我的代码没有像这篇博文的作者指出的那样遇到Database.SetInitializer;。我的构造函数看起来和他的一模一样。我的DbContext 初始化如下:

public DatabaseEntities(DbConnection connection) 
     : base(connection, true) { }

当到达前面提到的覆盖 OnModelCreating 时会导致以下异常

System.Data.Entity.Infrastructure.UnintentionalCodeFirstException: '上下文在 Code First 模式下使用,代码是从 EDMX 文件生成的,用于 Database First 或 Model First 开发。这将无法正常工作。要解决此问题,请不要删除引发此异常的代码行。如果您希望使用 Database First 或 Model First,请确保 Entity Framework 连接字符串包含在启动项目的 app.config 或 web.config 中。如果要创建自己的 DbConnection,请确保它是 EntityConnection 而不是其他类型的 DbConnection,并且将其传递给采用 DbConnection 的基本 DbContext 构造函数之一。要了解有关 Code First、Database First 和 Model First 的更多信息,请参阅此处的实体框架文档:http://go.microsoft.com/fwlink/?LinkId=394715'

stackoverflow 上有很多问题都集中在单元测试上,同时使用数据库优先的方法,但似乎没有人像我一样遇到类似的问题。

我已经尝试过的事情

  • 在互联网上搜索了很长时间的解决方案。
  • 取消注释被覆盖的OnModelCreating()
  • 我已经尝试申请this solution,但没有成功。
  • Moq 模拟我的DbContext,这绝对不是一个选项。

问题

如何创建和使用内存数据库(努力)?


其他信息

当我取消注释 OnModelCreating() 时,第一次访问 DataContext 时将引发异常。例如:

DbConnection effortConnection = Effort.DbConnectionFactory.CreatePersistent("MockedDatabaseEntities");

using (DatabaseEntities dataContext = new DatabaseEntities(effortConnection))
{
    dataContext.Students.Count(); // Exception throws here
}

System.Data.Entity.ModelConfiguration.ModelValidationException: '在模型生成过程中检测到一个或多个验证错误: MyApplication.Shared.Model.KeyValuePair: : EntityType 'KeyValuePair' 没有定义键。定义此 EntityType 的键。 KeyValuePairs: EntityType: EntitySet 'KeyValuePairs' 基于没有定义键的类型'KeyValuePair'。'

【问题讨论】:

  • 取消注释 OnModelCreating 时有什么问题(因为我们需要以某种方式摆脱它)?如果每次构建模型时都重新创建它,则可以将 DatabaseEntities 子类化并用不会爆炸的东西再次覆盖它。
  • 附带说明;如果您将 Effort 与 pr 测试内存数据库(瞬态)一起使用,则 ownsDbConnection 在测试期间应该为 false(您的基本构造函数的布尔参数)。
  • 如果其他一切都失败了,我在 db-first'ish 环境中工作,但我手动将实体映射到 SQL 表。
  • @RobertJørgensgaardEngdahl - 我已经更新了我的问题。提前谢谢!
  • 从错误“EntityType 'KeyValuePair' has no key defined”中,您必须以某种方式指示 EntityFramework 您有一个密钥。您可以在 OnModelCreating 中执行此操作,就像在这里完成 stackoverflow.com/a/13612347/2154774

标签: c# entity-framework unit-testing entity-framework-6 effort


【解决方案1】:

问题是我必须为我的 KeyValuePair 数据集指定密钥。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<KeyValuePair>().HasKey(x => x.Key);
    base.OnModelCreating(modelBuilder, null);
}

非常感谢Robert Jørgensgaard Engdahl

【讨论】:

    【解决方案2】:

    如果有人正在寻找 db-first 方法的解决方案,这对我有用:

    string connStr = @"metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;";
    DbConnection connection = EntityConnectionFactory.CreateTransient(connStr);
    return new MyDatabaseContext(connection);
    

    我从我的 web/app.config 中获得了 connStr 部分。
    还有,我没碰OnModelCreating

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多