使用 InMemoryDatabase 时如何禁用预先加载

4im*_*ble 4 entity-framework entity-framework-core

我有一个未启用延迟加载的 EF.Core 2.1 DataContext。

我的配置是这样的:

services.AddDbContext<DataContext>(options =>  
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Run Code Online (Sandbox Code Playgroud)

我的测试使用相同的 DataContext 但使用不同的选项,如下所示:

options.UseInMemoryDatabase(databaseName: "ProjectSpecs")
Run Code Online (Sandbox Code Playgroud)

这一切都很好,只是我在内存中的 DataContext 急切地加载了所有内容。

如果我要求一个实体,它是否正在加载所有相关对象。

这意味着如果我想实际加载相关属性而忘记这样做,我的测试会在加载相关实体时通过。但在实际应用中由于.include被遗忘而失败。

我可以让内存中的 DataContext 表现得和真实的一样吗?

Cra*_* W. 5

我遇到了同样的问题,在阅读了一堆关于这个主题的文章后,我得出的结论是,这个问题真的是因为被测代码正在从 ChangeTracker 读取,其中测试代码已经组装了对象图。有了这些知识,我使用了我的 DbContext 并覆盖了 SaveChanges 方法,如下所示。

public override int SaveChanges()
{
    var affectedRows = base.SaveChanges();

    if (Database.ProviderName == "Microsoft.EntityFrameworkCore.InMemory")
    {
        ChangeTracker.Entries()
            .Where(e => e.Entity != null)
            .ToList()
            .ForEach(e => e.State = EntityState.Detached);
    }

    return affectedRows;
}
Run Code Online (Sandbox Code Playgroud)

通过分离 ChangeTracker 中的每个对象,它会强制被测代码返回数据库,而不是从 ChangeTracker 中提取现有的对象图。