导航属性没有正确加载

本文关键字:加载 属性 导航 | 更新日期: 2023-09-27 18:06:02

我的上下文看起来像:

public class ApplicationDbContext: IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
        this.Configuration.LazyLoadingEnabled = true;
    }
    //DbSet properties
}

所以,延迟加载是启用的。

我有以下类:

public class Home
{
    private ICollection<Slide> _slides;
    [Key]
    [Required]
    public string Name { get; set; }
    [ForeignKey("Header")]
    public int? HeaderID { get; set; }
    //Navigation properties
    public ICollection<Slide> Slides
    {
        get { return _slides ?? (_slides = new List<Slide>()); }
        set { _slides = value; }
    }
    public Content Header { get; set; }
}

注意,导航属性HeaderSlides都使用,没有使用 virtual关键字。据我所知,当我们不使用virtual关键字时,属性应该主动加载。

然而,当我从数据库中得到我的Home实体时,我的导航属性都是null(但属性HeaderID有值)。
即使我切换到this.Configuration.LazyLoadingEnabled = false; -属性未加载-他们仍然null .

下面是我如何从db获取数据(使用存储库模式):

public static Home GetHomeComponent(
    this IRepositoryAsync<Home> repository)
{
   var result = repository
       .Query()
       .Select()
       .First();
   return result;
}

我解决了Include属性的问题:

public static Home GetHomeComponent(
    this IRepositoryAsync<Home> repository)
{
   var result = repository
       .Query()
       .Include(x => x.Header)
       .Include(x=>x.Slides)
       .Select()
       .First();
   return result;
}

然而,这对我来说并不方便(因为我有太多的导航属性要加载)。

我的问题是:
使用virtual关键字-但为什么我的导航属性不加载急切?
还是我做错了什么?有没有其他方法来加载我的导航属性,而不使用Include ?

导航属性没有正确加载

如果你不使用virtual关键字,这只意味着一旦你试图访问非虚拟财产,它不会从数据库加载,但你会得到一个Null

这并不意味着你将有实体的所有属性立即填充,填充Slides的例子在你的代码中,你必须使用。include() -这是渴望加载,加载属性由你自己使用之前。

你可以创建一个泛型函数,它将通过它获得的参数(使用params)填充所需的属性,详见这里:

EntityFramework Eager Load所有导航属性