实体框架延迟加载不工作1.*单向关系

本文关键字:关系 工作 框架 延迟加载 实体 | 更新日期: 2023-09-27 18:01:36

我有以下实体

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"))

由于某些原因,实体框架在请求对象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()

返回实体本身,而不是代理类型。这表明属性ProxyCreationEnabled是false,但我已经仔细检查过了,它被设置为true。

编辑2

好了,终于找到问题了。我已经将b的构造函数设置为private,这当然使得不可能用代理类扩展对象。因此,导航属性被设置为null

实体框架延迟加载不工作1.*单向关系

我已经修改了你的代码,使工作与延迟加载。只要复制粘贴,一切都会好的。

在写行之前用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;
         }
     }
 }