有人可以告诉我为什么相关的Article
实体没有加载到.Include(a => a.Article)
上吗?即使NULL
确实具有值,它们也始终为ArticleId
。 FrontPageItem
和Article
之间的关系是1-0..1。 Article
可以不与FrontPageItem
有任何连接而存在,但是FrontPageItem
必须有一个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);
}
答案 0 :(得分:0)
首先,您需要了解急切加载,延迟加载,显式加载
急切加载
快速加载可帮助您一次加载所有需要的实体; 也就是说,您的所有子实体都将在单个数据库调用中加载。 这可以通过使用Include方法来实现, 相关实体作为查询的一部分,并且大量数据是 一次加载。
延迟加载
这是实体框架的默认行为,其中子 实体仅在首次访问时才加载。它 只是延迟了相关数据的加载,直到您要求。
显式加载
在实体框架中有一些选项可以禁用延迟加载。 关闭“延迟加载”后,您仍然可以通过以下方式加载实体 显式调用相关实体的Load方法。有 加载方法参考的两种使用方法(加载单个导航 属性)和集合(以加载集合)
因此,要加载关系实体,可以使用Microsoft.EntityFrameworkCore.Proxies包来启用延迟加载。因此,当您查询数据库EF时,它将基于它们之间的关系返回关系数据库
我的示例代码如下
services.AddDbContextPool<ApplicationDbContext>(options =>
options.UseLazyLoadingProxies().UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("AwesomeCMSCore")).UseOpenIddict());
如果您有任何问题,请告诉我