Entity framework 延迟加载在 1..* 单向关系中不起作用

Entity framework lazy loading not working in 1..* unidirectional relationship

我有以下实体

public class A
{
    public int AId {get; set;}
}

public class B
{
    public int BId {get; set;}
    public virtual A Child1 {get; set;}
    public virtual A Child2 {get; set;}
}

配置如下

modelBuilder.Entity<B>()
            .HasRequired(x => x.Child1)
            .WithMany()
            .Map(x => x.MapKey("Child1Id"))

modelBuilder.Entity<B>()
            .HasRequired(x => x.Child2)
            .WithMany()
            .Map(x => x.MapKey("Child2Id"))

出于某种原因,Entity Framework 在请求对象 B 的实体时不会延迟加载 Child1 或 Child2 属性。即

var b1 = context.Bs.FirstOrDefault();
Assert.IsNull(b.Child1) // true
Assert.IsNull(b.Child2) // true

但如果我明确加载它们,它就会工作。

var b2 = context.Bs.Include(x => x.Child1).Include(x => x.Child2).FirstOrDefault();
Assert.NotNull(b2.Child1) // true
Assert.NotNull(b2.Child2) // true

有谁知道为什么属性没有延迟加载?

编辑

好像

context.Bs.FirstOrDefault()

returns 实体本身而不是代理类型。这表明 属性 ProxyCreationEnabled 是假的,但我仔细检查了它并将其设置为真。

编辑 2

好的,终于找到问题了。我已将 Bs 构造函数设置为私有,这当然使得无法使用代理 class 扩展对象。因此,导航属性设置为 null。

我修改了您的代码,以便使用延迟加载。只需复制粘贴,一切都应该没问题。

在写入行之前用VS检查b1,你会看到延迟加载的对象,不要被长实体名吓到,因为我已经启用了代理创建。

 public class Program
 {
     public static void Main(string[] args)
     {
         Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());

         using (var myDbContext = new MyDbContext("DefaultConnection"))
         {
             var a1 = new A();
             var a2 = new A();

             var b1 = new B
             {
                 Child1 = a1,
                 Child2 = a2
             };

             myDbContext.Bs.Add(b1);
             myDbContext.SaveChanges();
         }

         using (var myDbContext = new MyDbContext("DefaultConnection"))
         {
             var b1 = myDbContext.Bs.FirstOrDefault();
             b1.ToString();
             Console.WriteLine(b1.ToString());
         }
     }

     public class A
     {
         public int AId { get; set; }
     }

     public class B
     {
         public int BId { get; set; }
         public virtual A Child1 { get; set; }
         public virtual A Child2 { get; set; }
     }

     public class MyDbContext : DbContext
     {
         public DbSet<A> As { get; set; }
         public DbSet<B> Bs { get; set; }

         protected override void OnModelCreating(DbModelBuilder modelBuilder)
         {
             modelBuilder.Entity<B>()
                 .HasRequired(x => x.Child1)
                 .WithMany()
                 .Map(x => x.MapKey("Child1Id")).WillCascadeOnDelete(false);

             modelBuilder.Entity<B>()
                 .HasRequired(x => x.Child2)
                 .WithMany()
                 .Map(x => x.MapKey("Child2Id")).WillCascadeOnDelete(false);

             base.OnModelCreating(modelBuilder);
         }

         public MyDbContext(string connectionString)
           : base("name=" + connectionString)
         {
             this.Configuration.LazyLoadingEnabled = true;
             this.Configuration.ProxyCreationEnabled = true;
         }
     }
 }