为什么没有在.Include()上加载相关实体? [英] Why aren't related entities loaded on .Include()?
问题描述
有人可以告诉我为什么相关的Article
实体没有加载到.Include(a => a.Article)
上的原因吗?即使ArticleId
确实具有值,它们始终为NULL
. FrontPageItem
和Article
之间的关系是1-0..1. Article
可以不与FrontPageItem
进行任何连接而存在,但是FrontPageItem
必须具有一个Article
.
Can anybody tell me why the related Article
entities are not being loaded on .Include(a => a.Article)
? They are always NULL
even though ArticleId
does indeed have a value. The relationship between FrontPageItem
and Article
is 1-0..1. An Article
can exist without any connection to a FrontPageItem
, but a FrontPageItem
must have one Article
.
在一个相当丑陋的解决方法中,我求助于foreach
-遍历列表中的所有返回项,然后手动添加Article
,如下面的索引方法所示.
In a rather ugly workaround, I have resorted to foreach
-ing through all the returned items in the list and adding Article
manually, as you can see in my index-method below.
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);
}
推荐答案
首先,您需要了解急切加载,延迟加载,显式加载
First you need to understand about Eager Loading, Lazy Loading, Explicit loading
急切加载
快速加载可帮助您一次加载所有需要的实体; 也就是说,您的所有子实体都将在单个数据库调用中加载. 这可以通过使用Include方法来实现,该方法将 相关实体作为查询的一部分,并且大量数据是 一次加载.
Eager Loading helps you to load all your needed entities at once; i.e., all your child entities will be loaded at single database call. This can be achieved, using the Include method, which returs the related entities as a part of the query and a large amount of data is loaded at once.
延迟加载
这是实体框架的默认行为,其中子 仅在首次访问实体时才加载该实体.它 只是延迟了相关数据的加载,直到您提出要求为止.
It is the default behavior of an Entity Framework, where a child entity is loaded only when it is accessed for the first time. It simply delays the loading of the related data, until you ask for it.
显式加载
在实体框架中有一些选项可以禁用延迟加载. 关闭延迟加载"后,您仍然可以通过以下方式加载实体 显式调用相关实体的Load方法.有 加载方法参考的两种使用方法(加载单个导航 属性)和集合(以加载集合)
There are options to disable Lazy Loading in an Entity Framework. After turning Lazy Loading off, you can still load the entities by explicitly calling the Load method for the related entities. There are two ways to use Load method Reference (to load single navigation property) and Collection (to load collections)
因此,要加载关系实体,可以使用Microsoft.EntityFrameworkCore.Proxies包来启用延迟加载.因此,当您查询数据库EF时,EF将根据它们之间的关系返回关系数据
So to load relational entity you can use Microsoft.EntityFrameworkCore.Proxies package to enable lazy loading. So when you query database EF will return relational data base on their relationship
我的示例代码如下
services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseLazyLoadingProxies().UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("AwesomeCMSCore")).UseOpenIddict());
如果您有任何问题,请告诉我
Please let me know if you have any problem
这篇关于为什么没有在.Include()上加载相关实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!