C#:我应该对每个相关属性使用延迟加载吗?

问题描述 投票:0回答:1

我正在研究延迟加载。我不明白延迟加载是如何工作的,我应该做些什么来改变它吗?

这是我的第一个案例:我有

User
User roles
Roles
课程。用户与角色具有多对多的关系。所以我创建了用户角色类来处理这种关系。用户不包含所有情况下的角色(不介意 UserRole 中的
Id
)。

用户

public class User : IUser { public bool IsActive { get; set; } public int Id { get; private set; } public string Email { get; set; } public byte[] PasswordHash { get; set; } public byte[] PasswordSalt { get; set; } public string? Phone { get; set; } public List<UserRole> UserRoles { get; set; } }

用户角色

public class UserRole : IEntity { public int Id { get; private set; } [ForeignKey(nameof(User))] public int UserId { get; set; } public User User { get; set; } [ForeignKey(nameof(Role))] public int RoleId { get; set; } public Role Role { get; set; } }

角色

public class Role : IEntity { public int Id { get; private set; } public string Name { get; set; } }
这是我的第二个案例:我有一个与

Article

有关系的
User
类。在这种情况下,
Article
 使用 
Creator.Email
 (
User
) 或任何情况下的创建者名称,这意味着使用 
User
 的任何查询都包含 
Article

文章

public class Article : IEntity { public Article() => CreatedAt = DateTime.Now; public bool IsDeleted { get; set; } public int Id { get; private set; } public string Title { get; set; } = "Başlık"; public string Content { get; set; } = "İçerik"; public DateTime CreatedAt { get; set; } public DateTime? UpdatedAt { get; set; } [ForeignKey(nameof(User))] public int CreatorId { get; set; } [ForeignKey(nameof(User))] public int? DeletedBy { get; set; } public User? Creator { get; set; } public List<ArticleCategory> ArticleCategories { get; set; } }
所以我的问题是:我应该做些什么来延迟加载这些相关属性吗?

如果是 - 我该怎么办?如果不是 - 这如何与 EF Core 配合使用?

对于

User

 的示例,它是从数据库返回数据并将其保存在内存中直到被请求,还是在被请求之前不会进入 UserRoles 和 Roles 表?

如果两者都不是,它实际上是如何工作的?

这是我如何以非常简单的方式从数据库获取所有数据的示例:

var users = context.Users .Include(u => u.UserRoles) .ThenInclude(ur => ur.Role);
在某些情况下,即使我不请求用户的角色,它们是否会从数据库中获取,如果是,它们是否会保留在内存中?

c# .net entity-framework linq lazy-loading
1个回答
2
投票

Lazy<T>

是一个框架提供的类,用于支持任何自定义开发人员定义的逻辑/函数的延迟初始化(通常用于多线程环境,但不限于此)。与 EF Core 无关。

另一方面,EF Core 中数据的

延迟加载是在不使用Lazy

的情况下完成的(至少在面向用户的 API/约定中)。 EF 中有两种主要的延迟加载“风格” - 
with proxywithout。第一种方法依赖于使用特殊的包,并且需要相应的属性是虚拟的:

public class Blog { // ... public virtual ICollection<Post> Posts { get; set; } } public class Post { // ... public virtual Blog Blog { get; set; } }
这会生成特殊的代理类,除非需要(即以某种方式访问),否则它将推迟相关数据的加载。例如:

var post = _context.Posts.First(); // the Blog will not be loaded // ... var postBlog = post.Blog; // here the lazy loading will happen.
这两个概念相关,但仍然有些不同。

附注

  • 需要注意的一件事 - EF DbContext 不是线程安全的(即一次只能由一个线程使用,并且不支持通过同一实例对数据库进行并行查询),这消除了一部分问题,通过以下方式解决

    Lazy

  • 我个人建议谨慎使用延迟加载,因为它可能导致臭名昭著的 N+1 问题 - 请检查文档的

    注意延迟加载部分。

© www.soinside.com 2019 - 2024. All rights reserved.