4

我们正在使用Effort.EF6为针对内存数据库的 ASP.NET Web API 2 服务构建一个测试套件,并且在大多数情况下,这是一次美妙的体验。

但是,由于与这个问题无关的原因,我们不得不在 EF6 中关闭延迟加载(通过Configuration.LazyLoadingEnabled = false; 在 db 上下文的构造函数中运行),这意味着如果我们忘记.Include()某个关系并稍后使用它,我们会得到NullReferenceExceptions. 我们希望我们的测试能够捕捉到这些类型的错误。

我们的测试设置基本上如下:

  1. 使用 Effort 的连接工厂创建一个数据库连接。这是每个测试的唯一连接实例(当我们尝试使用持久连接时,具有唯一键)。
  2. 使用该连接创建一个数据库上下文,并添加我们希望为测试存在的数据。
  3. 在 DI 容器中为 db 上下文注册服务覆盖。

问题是我们无法弄清楚如何配置 Effort.EF6 以禁止延迟加载,因为似乎我们在测试设置中添加到上下文中的任何内容在测试代码运行时都已经加载,因此我们从来没有见例外。我们假设这是因为我们在测试设置和实际代码执行之间重用了上下文实例。

如果我们尝试将第三步切换为以下:

  1. 在 DI 容器中为 db 连接注册服务覆盖。
  2. DI 容器创建一个 db 上下文实例(将 db 连接作为注入依赖项)

相反,我们最终得到了一个的数据库上下文,即尽管我们在运行测试之前添加了一些数据点,但它没有数据。

我们如何使用 Effort 构造和注入数据库上下文,如果.Include()语句丢失,它将失败,但如果它存在则工作?

4

1 回答 1

0

您也必须在 Effort.EF6 的构造函数中停用它 - 获取DbConnection对象的那个。

我为我的 EF Code First 项目解决了这个问题,如下所示:

public class MyDataContext : DbContext, IMyDataContext
{
    /*
    * the ohter stuff like IDbSet<T> etc.
    */


    public MyDataContext() : base("name=MyConnectionString")
    {
        Configure();
    }

    /// <summary>
    /// This constructor is for test usage only!
    /// </summary>
    /// <param name="connection">Test connection for in memory database</param>
    public MyDataContext(DbConnection connection) : base(connection, true)
    {
        Configure();
    }


    /// <summary>
    /// Configures the data context.
    /// </summary>
    private void Configure()
    {
        Configuration.LazyLoadingEnabled = false;
    }
}

此外,在我的测试项目中,我正在设置测试 CSV 文件。Effort.EF6 将使用这些文件来实例化带有种子数据的上下文。在我的例子中,我编写了一个小的 TestDataManager,它可以为特定的表添加特定的文件。

下面是一段代码,您可以如何使用 Effort.EF6 播种数据:

IDataLoader loader = new CsvDataLoader(@"C:\Temp\Test_CSV_Files");
DbConnection dbConnection = DbConnectionFactory.CreateTransient(loader);
var myDataContext = new MyDataContext(dbConnection);

也许这篇博文也可以帮助你。

于 2017-10-20T14:12:05.460 回答