EF6代码首次延迟加载导致空集合

N-ate

这样就创建了动态代理,但是我无法弄清楚为防止导航属性延迟加载而做错了什么。这是我运行以测试该问题的确切代码。

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档