实体框架延迟加载不工作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
我已经修改了你的代码,使工作与延迟加载。只要复制粘贴,一切都会好的。
在写行之前用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;
}
}
}