考虑以下EF core 3.1数据模型:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public Blog Blog { get; set; }
public int BlogId { get; set; }
}
public class BlogAppContext: DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=DB_BLOG_APP;Integrated Security=SSPI;MultipleActiveResultSets=True");
}
public DbSet<Post> Posts { get; set; }
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasMany(x => x.Posts)
.WithOne(x => x.Blog)
.HasForeignKey(x => x.BlogId)
.IsRequired();
}
}
考虑一个场景,在该场景中,我使用热切加载来运行以下查询:
static void Main(string[] args)
{
using var context = new BlogAppContext();
var blogs = context.Blogs.Include(x => x.Posts).ToList();
foreach (var blog in blogs)
{
Console.WriteLine($"There are {blog.Posts.Count} posts");
}
}
通过查看一些示例,我注意到初始化列表导航属性是一种常见的做法。在我的情况下,这将导致这样的事情:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public List<Post> Posts { get; set; } = new List<Post<();
}
我在问,当通过热切加载进行查询时,这是否真的有用。
我已经做了一些测试,并验证了上面显示的查询是否会自动为没有帖子的博客创建一个空列表。
换句话说,似乎即使Posts
导航属性未初始化为Blog
实体定义内的空列表,使用热切加载的查询也不会在意,并且不会为Posts
导航属性返回null
值。
我的理解正确吗?
如果是,当使用热切加载来加载相关实体来查询数据库时,将Posts
导航属性初始化为空列表有什么用处(如果有的话(?
这是没有用的,您不必这样做,因为您使用的是急切加载(如果您加载了很多不必要的数据,这不是很有效,但这是另一个主题(。
然而,这在两种情况下是有用的:
- 如果因为
Posts
属性可能是null
而不使用热切加载 - 您正在创建一个尚未保存在数据库中的新
Blog
对象,并希望向其中添加一个新的Post
。在这种情况下,必须在调用Posts.Add(post)
之前初始化Posts
属性,因为将引发null ref单元化异常