实体框架核心:如何在使用内存数据存储时测试导航属性加载

时间:2017-06-01 00:15:37

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

实体框架核心中存在一个有趣的特征:

  

Entity Framework Core将自动修复导航属性   到之前加载到上下文中的任何其他实体   实例。所以,即使你没有明确地包含a的数据   导航属性,如果某些或仍然可能填充该属性   以前加载了所有相关实体。

在某些情况下这很好。然而,目前我尝试使用高级语法添加建模多对多关系并且无法检查,我创建的映射效果很好。

但实际上我无法做到这一点,因为如果我们说我有类似的东西:

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预览1和EF核心。

1 个答案:

答案 0 :(得分:5)

如果您要使用内存数据存储来测试导航属性,则需要将项目加载到&#34;非跟踪&#34;模式,使用AsNoTracking()扩展名。

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

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