这样就创建了动态代理,但是我无法弄清楚为防止导航属性延迟加载而做错了什么。这是我运行以测试该问题的确切代码。
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
}
数据库:
我已验证数据库中已插入正确的信息。关系看起来不错。我确定我缺少明显的东西。
更新
这有效:
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
}
因此,内置延迟加载需要相同的数据库上下文。
要触发延迟加载,需要在处置上下文之前以某种方式访问属性。
您的测试代码在离开上下文之前不会访问属性:
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
属性,则会显示一条错误消息。
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属性,它将可用。
延迟加载的想法是,尽管上下文可用,但您第一次访问最初未加载的属性时,该属性将在此时加载。
请参阅本文,以了解使用EF加载实体的不同方式(快速,懒惰,显式):
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句