为什么在EF6中调用dbContext.Save后重置导航属性

cas4

背景:我正在使用EF6和数据库优先。

我遇到了一个让我感到困惑的场景。创建新对象,用新对象填充“导航属性”并调用SaveChanges之后,将重置导航属性。在SaveChanges调用之后,引用导航属性的第一行代码将最终从数据库中重新获取数据。这是预期的行为,有人可以解释为什么这样做吗?这是我的方案的示例代码块:

using (DbContext context = new DbContext) {
    Foo foo = context.Foos.Create();
    context.Foos.Add(foo);
    ...
    Bar bar = context.Bars.Create();
    context.Bars.Add(bar);
    ...
    FooBar foobar = context.FooBars.Create();
    context.FooBars.Add(foobar)
    foobar.Foo = foo;
    foobar.Bar = bar;

    //foo.FooBars is already populated, so 1 is returned and no database query is executed.
    int count = foo.FooBars.Count;

    context.SaveChanges();

    //This causes a new query against the database - Why?
    count = foo.FooBars.Count;
}
伊万·斯托夫(Ivan Stoev)

我不能说100%,但是我怀疑这种行为是专门做出的。

至于为什么会这样,问题的根源在于该DbCollectionEntry.IsLoaded属性是false直到导航属性隐式延迟加载或使用Loadmethod显式加载

同样,当实体处于“已添加”状态时,似乎也抑制了延迟加载,这就是为什么第一次调用不会触发重新加载的原因。但是,一旦调用SaveChanges,实体状态将变为未修改状态,尽管集合并没有真正设置为“ null”或未清除,但是下一次访问集合属性的尝试将触发延迟重新加载。

// ...

Console.WriteLine(context.Entry(foo).Collection(e => e.FooBars).IsLoaded); // false
//foo.FooBars is already populated, so 1 is returned and no database query is executed.
int count = foo.FooBars.Count;

// Cache the collection property into a variable
var foo_FooBars = foo.FooBars;

context.SaveChanges();

Console.WriteLine(context.Entry(foo).State); // Unchanged!
Console.WriteLine(context.Entry(foo).Collection(e => e.FooBars).IsLoaded); // false

// The collection is still there, this does not trigger database query
count = foo_FooBars.Count;
// This causes a new query against the database
count = foo.FooBars.Count;

如果要避免重新加载,解决方法是将IsLoaded属性显式设置true

// ...

context.SaveChanges();

context.Entry(foo).Collection(e => e.FooBars).IsLoaded = true;
context.Entry(bar).Collection(e => e.FooBars).IsLoaded = true;
// No new query against the database :)
count = foo.FooBars.Count;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

EF6:在DbSet.Local中包括导航属性

来自分类Dev

EF6升级后的额外SQL调用

来自分类Dev

可以使用EF6将包含的导航属性嵌套在Web API中吗?

来自分类Dev

如何在渴望加载的ASP.NET MVC中的EF6中包括导航属性的多个导航属性?

来自分类Dev

EF6不会延迟加载导航属性

来自分类Dev

阻止EF6生成导航属性

来自分类Dev

EF6不会延迟加载导航属性

来自分类Dev

EF6导航属性与单逆相同类型

来自分类Dev

为什么导航属性在EF中默认为虚拟

来自分类Dev

忽略EF6插入中的属性名称

来自分类Dev

为什么EF导航属性返回null?

来自分类Dev

为什么在EF6中忽略包括

来自分类Dev

从EF4升级后,在EF6中查询数据的空引用异常

来自分类Dev

具有相同类型导航属性集合的EF6代码第一实体-如何告诉EF是什么关系?

来自分类Dev

在每次访问后/在懒惰的getter中重置属性

来自分类Dev

手动附加后,EF解析导航属性

来自分类Dev

更新EF6时需要属性

来自分类Dev

忽略继承属性 EF6

来自分类Dev

在EF6中,什么可能导致错误无法更改关系,因为一个或多个外键属性不可为空

来自分类Dev

从集合中删除对象后,如何使EF6从数据库中删除对象?

来自分类Dev

将引用属性的引用属性加载到包含EF6中

来自分类Dev

为EF6中的所有属性创建自定义属性映射

来自分类Dev

如何使用扩展实体在EF6类中通过属性更改通知创建新属性?

来自分类Dev

为什么我的模型属性在回发后重置为null?

来自分类Dev

具有导航属性的EF6一对多流利的api

来自分类Dev

具有导航属性的EF6一对多流利的api

来自分类Dev

为什么Stack <T>不能在EF中作为导航属性

来自分类Dev

如何在EF6 Code First中更新虚拟属性?

来自分类Dev

检查“延迟加载”属性是否已在EF6中加载

Related 相关文章

  1. 1

    EF6:在DbSet.Local中包括导航属性

  2. 2

    EF6升级后的额外SQL调用

  3. 3

    可以使用EF6将包含的导航属性嵌套在Web API中吗?

  4. 4

    如何在渴望加载的ASP.NET MVC中的EF6中包括导航属性的多个导航属性?

  5. 5

    EF6不会延迟加载导航属性

  6. 6

    阻止EF6生成导航属性

  7. 7

    EF6不会延迟加载导航属性

  8. 8

    EF6导航属性与单逆相同类型

  9. 9

    为什么导航属性在EF中默认为虚拟

  10. 10

    忽略EF6插入中的属性名称

  11. 11

    为什么EF导航属性返回null?

  12. 12

    为什么在EF6中忽略包括

  13. 13

    从EF4升级后,在EF6中查询数据的空引用异常

  14. 14

    具有相同类型导航属性集合的EF6代码第一实体-如何告诉EF是什么关系?

  15. 15

    在每次访问后/在懒惰的getter中重置属性

  16. 16

    手动附加后,EF解析导航属性

  17. 17

    更新EF6时需要属性

  18. 18

    忽略继承属性 EF6

  19. 19

    在EF6中,什么可能导致错误无法更改关系,因为一个或多个外键属性不可为空

  20. 20

    从集合中删除对象后,如何使EF6从数据库中删除对象?

  21. 21

    将引用属性的引用属性加载到包含EF6中

  22. 22

    为EF6中的所有属性创建自定义属性映射

  23. 23

    如何使用扩展实体在EF6类中通过属性更改通知创建新属性?

  24. 24

    为什么我的模型属性在回发后重置为null?

  25. 25

    具有导航属性的EF6一对多流利的api

  26. 26

    具有导航属性的EF6一对多流利的api

  27. 27

    为什么Stack <T>不能在EF中作为导航属性

  28. 28

    如何在EF6 Code First中更新虚拟属性?

  29. 29

    检查“延迟加载”属性是否已在EF6中加载

热门标签

归档