我做了一个简单的例子来检查EF延迟加载行为并发现了一些非常奇怪的东西。我的例子如下:
class Foo
{
public int Id {get;set;}
public string Name {get;set;}
public virtual ICollection<Bar> Bars {get;set;}
}
class Bar
{
public int Id {get;set;}
public string Name {get;set;}
public int FooID {get;set;}
[ForeignKey("FooID")]
public virtual Foo Foo {get;set;}
}
class Context : DbContext
{
public DbSet<Foo> Foo {get;set;}
public DbSet<Bar> Bar {get;set;}
}
class Demo
{
static void Main(string[] args)
{
Context ctx = new Context();
var foos = ctx.Foo.ToList();
var bars = ctx.Bar.ToList();
Console.ReadLine();
}
}
如您所见,Foo
和Bar
之间存在一对多的关系。这里的预期行为是这些类中的Foo
和Bars
属性将被延迟加载。但是这里发生了意想不到的事情。
如果我同时运行两行
var foos = ctx.Foo.ToList();
var bars = ctx.Bar.ToList();
懒惰加载工作完美。
但如果我只运行其中一行:
var foos = ctx.Foo.ToList();
//var bars = ctx.Bar.ToList();
或者
//var foos = ctx.Foo.ToList();
var bars = ctx.Bar.ToList();
在这种情况下,延迟加载不起作用,我只在null
或Bars
属性中获得Foo
。有人可以解释一下这里发生了什么吗?
修改
笨拙的我发现这种情况发生是因为我没有将public
修饰符添加到Foo
的类定义和Bar
答案 0 :(得分:1)
您还不知道延迟加载是什么。
时会发生延迟加载
即。如果您有这样的实体
public class Parent
{
public int ParentId { get; set; }
public virtual ICollecton<Child> Children { get; set; }
}
当你这样做时
var parent = myContext.Parents.First()
你得到一个父母,没有子女来自数据库。此时,如果上下文尚未处理,您可以这样做:
foreach(var child in parent.Children)
如果这是您第一次访问Children
属性,则上下文将查询数据库并填充它。这是懒惰的装载。任何其他事情都不是懒惰的装载。
请阅读这篇文章,了解加载相关实体的所有可能方式(渴望,明确或懒惰):