EF6代码首次延迟加载导致空集合 [英] EF6 Code First Lazy Load results in null collection
问题描述
因此创建了动态代理,但是我无法弄清楚为防止延迟加载导航属性而做错了什么.这是我用来测试该问题的确切代码.
So the dynamic proxy is created, but I can't figure out what I've done wrong to prevent navigation properties from lazy loading. Here is the exact code I've run to test the issue.
DbContext:
public class MyDbContext : DbContext
{
public MyDbContext()
: base("MyConnection")
{
}
public DbSet<One> Ones { get; set; }
public DbSet<Many> Manies { get; set; }
}
课程:
public class One
{
public int Id { get; set; }
public virtual ICollection<Many> Manies { get; set; }
public One()
{
Manies = new List<Many>();
}
}
public class Many
{
public int Id { get; set; }
public string Value { get; set; }
public int OneId { get; set; }
public virtual One One { get; set; }
public Many()
{
}
}
测试:
[TestMethod]
public void OneToManyTest()
{
One parent1 = new One();
parent1.Manies.Add(new Many() { Value = "child 1" });
parent1.Manies.Add(new Many() { Value = "child 2" });
using (MyDbContext db = new MyDbContext())
{
db.Ones.Add(parent1);
db.SaveChanges();
}
Assert.IsTrue(parent1.Id > 0, "Id not set");
One parent2;
using (MyDbContext db = new MyDbContext())
{
db.Configuration.ProxyCreationEnabled = true;
db.Configuration.LazyLoadingEnabled = true;
parent2 = db.Ones.Find(parent1.Id);//parent2 is a dynamic proxy
}
Assert.AreEqual(parent1.Id, parent2.Id);
/*parent2.Manies is null*/
Assert.AreEqual(parent1.Manies.Count, parent2.Manies.Count);//fails
}
数据库:
我已验证数据库中已插入正确的信息.关系看起来不错.我确定我缺少明显的东西.
I've verified the correct information is being inserted in the database. The relationships look good. I'm sure I'm missing something obvious.
更新
这有效:
using (MyDbContext db = new MyDbContext())
{
db.Configuration.ProxyCreationEnabled = true;
db.Configuration.LazyLoadingEnabled = true;
parent2 = db.Ones.Find(parent1.Id);//parent2 is a dynamic proxy
Assert.AreEqual(parent1.Id, parent2.Id);
Assert.AreEqual(parent1.Manies.Count, parent2.Manies.Count);
}
这不是:
using (MyDbContext db = new MyDbContext())
{
db.Configuration.ProxyCreationEnabled = true;
db.Configuration.LazyLoadingEnabled = true;
parent2 = db.Ones.Find(parent1.Id);//parent2 is a dynamic proxy
}
using (MyDbContext db = new MyDbContext())
{
Assert.AreEqual(parent1.Id, parent2.Id);
Assert.AreEqual(parent1.Manies.Count, parent2.Manies.Count);//parent2.Manies is null
}
因此,内置延迟加载需要相同的数据库上下文.
So the same db context is required for built in lazy loading.
推荐答案
要触发延迟加载,您需要在处置上下文之前以某种方式访问属性.
To trigger lazy loading you need to access the property in some way, before disposing of the context.
您的测试代码在离开上下文之前不会访问属性:
Your test code doesn't acces the property before leaving the context:
One parent2;
using (MyDbContext db = new MyDbContext())
{
db.Configuration.ProxyCreationEnabled = true;
db.Configuration.LazyLoadingEnabled = true;
parent2 = db.Ones.Find(parent1.Id);//parent2 is a dynamic proxy
}
// Context disposed: thsi would throw an exception:
var manies = parent2.Manies.ToList()
至此,您的上下文已经处理完毕.如果您尝试访问Manies
属性,则会显示一条错误消息.
At this point, your context has been disposed. If you tried to access the Manies
property you'd get an error stating this.
One parent2;
using (MyDbContext db = new MyDbContext())
{
db.Configuration.ProxyCreationEnabled = true;
db.Configuration.LazyLoadingEnabled = true;
parent2 = db.Ones.Find(parent1.Id);//parent2 is a dynamic proxy
// Context available: this sill lazy load the Manies entities
var manies = parent2.Manies.ToList();
}
现在,如果您检查manies属性,它将可用.
Now, if you check the manies properties, it will be available.
延迟加载的想法是,尽管上下文可用,但第一次访问最初未加载的属性时,该属性将在此时加载.
The idea of lazy loading is that, while the context is available, the first time you access a property which wasn't loaded initially, it will be loaded at that moment.
请参阅本文以了解使用EF加载实体的不同方式(急切,懒惰,显式):
Please, see this article to understand the different ways (eager, lazy, explicit) of loading entities with EF:
这篇关于EF6代码首次延迟加载导致空集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!