我的上下文如下:
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; }
}
请注意,导航属性Header
和Slides
均使用而不是 virtual
关键字。 As far as I know当我们不使用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
的情况下加载导航属性?
答案 0 :(得分:12)
如果您不使用virtual
关键字,则仅表示一旦您尝试访问非虚拟属性,它就不会从数据库加载,但您将获得Null
。
这并不意味着您将立即填充实体的所有属性,在代码中填充Slides
EG,您必须使用.Include() - 这是加载,加载在使用之前由你自己的财产。
您可以创建一个泛型函数,通过它获取的参数填充所需的属性(使用params),请参阅此处了解更多详细信息: