.NET Core 2.0中Entity Framework如何Include多层关联引用?
解决EF Core多层关联数据加载的问题
你遇到的RuntimeBinderException本质是因为查询时没加载ModelB关联的Tokens集合,导致视图里访问关联属性时触发了空引用。结合你的代码场景,我给你一步步解决:
核心解决方案:用ThenInclude实现多层级Include
在EF Core中,要加载一级关联下的二级关联数据,需要用ThenInclude方法衔接Include。修改你的查询代码如下:
var request = await _context.Request .Include(r => r.Emails) .ThenInclude(e => e.Tokens) // 加载每个Email对应的Tokens集合 .SingleOrDefaultAsync(r => r.ID == id);
额外要修正的视图问题
注意看你的模型定义:ModelB里的关联属性是复数的Tokens(public List<ModelC> Tokens { get; set; }),但你视图里写的是@email.Token(单数),这本身就会导致找不到属性或者空引用。
如果ModelB和ModelC是一对多关系,视图需要遍历Tokens集合,比如:
@foreach (var email in Model.Emails) { <tr> <td>@email.Name</td> @foreach (var token in email.Tokens) { <td>@token.Token</td> <td>@token.getStatusName()</td> } </tr> }
如果每个ModelB只会对应一个ModelC,那你需要先修改模型,把List<ModelC> Tokens改成ModelC Token,再调整关联配置。
备选方案:字符串路径形式的Include(不推荐)
如果你习惯用字符串指定关联路径,也可以这么写,但强类型的ThenInclude更不容易出错:
var request = await _context.Request .Include("Emails.Tokens") .SingleOrDefaultAsync(r => r.ID == id);
小优化建议
把ModelC里的getStatusName()方法改成属性,更符合.NET开发习惯:
public string StatusName { get { var statuses = new[] { "Created", "Approved", "Rejected" }; return statuses[Status]; } }
这样视图里可以直接写@token.StatusName,代码更简洁。
内容的提问来源于stack exchange,提问作者user3257442
相关产品推荐
相关产品推荐

