实体框架延迟加载不能在1 .. *单向关系中

时间:2016-08-10 12:17:42

标签: c# entity-framework entity-framework-6 lazy-loading

我有以下实体

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

返回实体本身而不是代理类型。这表明该财产 ProxyCreationEnabled为false但我已经仔细检查了它并将其设置为true。

编辑2

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

1 个答案:

答案 0 :(得分: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;
         }
     }
 }