非数据库创建的实体实例如何实现reference("field").Load()与Include等效功能
直接加载脱管实体关联集合的实现方案
你要的等效Load()和Include的直接实现可以通过EF内置的Entry.Collection方法完成,不需要额外查询完整的旧实体记录,示例代码如下:
方案1:直接加载关联集合(无深层关联需求)
[HttpPost] public ActionResult Edit(User user) { // 先将视图返回的脱管User实例附加到当前上下文 db.Users.Attach(user); // 直接加载AllowedOrganizations关联集合数据 db.Entry(user).Collection(u => u.AllowedOrganizations).Load(); // 此时user.AllowedOrganizations已填充数据库中存储的对应数据,直接遍历即可 foreach (LinkUserOrganization oldlink in user.AllowedOrganizations) { if (AllowedOrganizationIdentifiers.Contains(oldlink.OrganizationId)) { db.Entry(oldlink).State = EntityState.Unchanged; AllowedOrganizationIdentifiers.Remove(oldlink.OrganizationId); } else { db.Entry(oldlink).State = EntityState.Deleted; } } // 剩余业务逻辑 }
方案2:需要加载深层关联时链式调用Include
如果需要同时加载LinkUserOrganization下的关联属性(比如Organization),可以通过Query()方法扩展,等效于原Include写法:
db.Users.Attach(user); db.Entry(user) .Collection(u => u.AllowedOrganizations) .Query() // 此处可按需添加任意层级的Include/ThenInclude加载深层关联 .Include(l => l.Organization) .Load();
注意事项
- 附加实体前如果不确定当前上下文是否已跟踪同ID的User实例,可先检查本地跟踪缓存避免冲突:
var localTrackedUser = db.Users.Local.FirstOrDefault(u => u.Id == user.Id); if (localTrackedUser != null) { user = localTrackedUser; } else { db.Users.Attach(user); }
- 异步场景下可替换为
LoadAsync()方法提升吞吐性能。
内容的提问来源于stack exchange,提问作者Nik Volk
相关产品推荐
相关产品推荐

