c# - 为什么 .Include() 上没有加载相关实体?
问题描述
谁能告诉我为什么Article
没有加载相关实体.Include(a => a.Article)
?NULL
即使ArticleId
确实具有价值,它们也总是如此。FrontPageItem
和之间的关系Article
是1-0..1。AnArticle
可以存在而与 a 没有任何联系FrontPageItem
,但 aFrontPageItem
必须有一个Article
。
在一个相当丑陋的解决方法中,我已经foreach
通过列表中的所有返回项目并Article
手动添加,正如您在下面的索引方法中看到的那样。
public async Task<IActionResult> Index()
{
List<FrontPageItem> items = await db.FrontPageItems
.Include(a => a.Article)
.ThenInclude(c => c.CreatedBy)
.ThenInclude(m => m.Member)
.Include(a => a.Article)
.ThenInclude(e => e.EditedBy)
.ThenInclude(m => m.Member)
.Include(a => a.Article)
.ThenInclude(e => e.PublishReadyBy)
.ThenInclude(m => m.Member)
.Include(p => p.WebPage)
.OrderByDescending(o => o.DatePublished)
.ToListAsync();
// I don't want to foreach, but without it, Article is always NULL for all items.
foreach (FrontPageItem item in items)
{
item.Article = await db.Articles
.Where(a => a.Id == item.ArticleId).FirstOrDefaultAsync();
}
List<FrontPageItemViewModel> vm =
auto.Map<List<FrontPageItemViewModel>>(items);
return View(vm);
}
这些是模型:
public class FrontPageItem
{
public int Id { get; set; }
// ... some more properties
public int? ArticleId { get; set; }
public Article Article { get; set; }
public AdminUser CreatedBy { get; set; }
public AdminUser EditedBy { get; set; }
public AdminUser PublishedBy { get; set; }
}
public class Article
{
public int Id { get; set; }
// ... some more properties
public int? FrontPageItemId { get; set; }
public FrontPageItem FrontPageItem { get; set; }
public AdminUser CreatedBy { get; set; }
public AdminUser EditedBy { get; set; }
public AdminUser PublishReadyBy { get; set; }
}
public class AdminUser
{
public int Id { get; set; }
// ... some more properties
public int MemberId { get; set; }
public Member Member { get; set; }
}
public class Member
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// ... some more properties
public AdminUser AdminUser { get; set; }
}
这是模型构建器:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Article>()
.HasOne(p => p.FrontPageItem)
.WithOne(i => i.Article)
.HasForeignKey<Article>(b => b.FrontPageItemId);
}
解决方案
首先你需要了解 Eager Loading、Lazy Loading、Explicit loading
急切加载
Eager Loading 可帮助您一次加载所有需要的实体;即,您的所有子实体都将在单个数据库调用中加载。这可以使用 Include 方法来实现,该方法将相关实体作为查询的一部分返回,并且一次加载大量数据。
延迟加载
这是实体框架的默认行为,其中子实体仅在第一次访问时才加载。它只是延迟加载相关数据,直到您提出要求。
显式加载
在实体框架中有禁用延迟加载的选项。关闭延迟加载后,您仍然可以通过显式调用相关实体的 Load 方法来加载实体。有两种方法可以使用 Load 方法 Reference(加载单个导航属性)和 Collection(加载集合)
因此,要加载关系实体,您可以使用 Microsoft.EntityFrameworkCore.Proxies 包来启用延迟加载。因此,当您查询数据库时,EF 将根据它们的关系返回关系数据库
我的示例代码看起来像这样
services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseLazyLoadingProxies().UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("AwesomeCMSCore")).UseOpenIddict());
如果您有任何问题,请告诉我
推荐阅读
- python - 显示数字是否在 pandas 中最多 3 个位置是连续的
- python - 为什么我会丢失 Flask 应用程序中重定向的会话信息?
- c# - 计算一段时间后工作了多少小时
- javascript - 错误:app.database 不是使用 Firebase 的函数
- reactjs - 无法在反应中执行循环
- windows - 在 Powershell 脚本中的标签中显示文本
- javascript - angular2 - 在外部组件的控制器中获取内部组件的 DOM 元素?
- c# - C#删除边界内的字符串
- python - Python CSV 错误:行包含 NULL 字节,但在文件中找不到 NULL 字节
- ios - 在 Swift 中,从 App Extension 目标运行时如何忽略部分代码?