【问题标题】:Entity framework core: How to test navigation propery loading when use in-memory datastore实体框架核心:使用内存数据存储时如何测试导航属性加载
【发布时间】:2017-06-01 00:15:37
【问题描述】:

实体框架核心中有一个有趣的特性:

Entity Framework Core 将自动修复导航属性 到之前加载到上下文中的任何其他实体 实例。因此,即使您没有明确包含 导航属性,如果某些或 所有相关实体之前都已加载。

这在某些情况下很好。但是,目前我正在尝试使用高级语法添加对多对多关系进行建模,并且不想检查我创建的映射是否运行良好。

但我实际上做不到,因为假设我有类似的东西:

class Model1{
   ... // define Id and all other stuff
   public ICollection<Model2> Rel {get; set;}
}

Model1 m1 = new Model1(){Id=777};
m1.Rel.Add(new Model2());
ctx.Add(m1);
ctx.SaveChanges()

var loaded = ctx.Model1s.Single(m => m.Id == 777);

所以由于自动修复loaded.Rel 字段已经被填充,即使我没有包含任何内容。所以有了这个功能,我实际上什么也不能检查。无法检查我是否使用了正确的映射,以及我对Include 的添加是否正常工作。考虑到这一点,我应该改变什么才能真正测试我的导航属性是否正常工作?


我创建了一个应该通过但现在失败的测试用例。 Exact code could be found there

据此,我正在使用 .Net Core 2.0 preview 1 和 EF core。

【问题讨论】:

  • 您可以创建一个没有创建实体的新 DbContext 并对其进行第二次查询,但您需要将其注入 DbContextOptions 并将其传递给其构造函数
  • 是的。我试过了。但是似乎在创建新 DbContext 时使用内存数据存储时,它会创建完全干净的内存存储(即使选项中的 DB 名称放置相同),因此在新上下文中没有以前保存的数据,这一事实再次不允许测试任何东西。
  • @Tseng 我在问题正文中添加了实际的失败案例,所以你可以检查一下,如果我做错了什么。
  • 导航已修复,因为正在上下文中跟踪相关实体。由于您使用的是相同的上下文来保存它们发生的情况。您需要将测试代码与设置代码隔离开来。
  • @Smit 这怎么可能?创建新上下文时 - 它不包含任何数据。我的意思是原则上。 newCtx.Models1 对于内存中的新上下文为空。至少对我来说,也许我做错了什么。

标签: asp.net-core entity-framework-core navigation-properties


【解决方案1】:

如果您想使用内存数据存储测试导航属性,您需要使用 AsNoTracking() 扩展以“非跟踪”模式加载您的项目。

所以,对于你的情况,如果 var loaded = ctx.Model1s.Single(m =&gt; m.Id == 777); 向您返回带有关系的项目,而不是如果您重写为:
var loaded = ctx.Model1s.AsNoTracking().Single(m =&gt; m.Id == 777); 这将返回您没有依赖关系的原始项目。

如果你想再次检查Include,你可以写ctx.Model1s.AsNoTracking().Include(m =&gt; m.Rel).Single(m =&gt; m.Id == 777);这样的东西,这将返回你包含关系的模型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-26
    • 2012-03-24
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多