Entity Framework Core 5 重新加载问题
Posted
技术标签:
【中文标题】Entity Framework Core 5 重新加载问题【英文标题】:Entity Framework Core 5 Reload issue 【发布时间】:2021-09-24 12:29:28 【问题描述】:我在插入后检索导航属性时遇到问题。
我正在使用此代码保存数据,但没有设置我不想更改的导航属性。 例如:
var entity = new MyEntity
FirstId = 1,
FirstObject = null
SecondId = 1,
SecondObject = null
//...data to update
;
_context.Update(myEntity);
_context.SaveChanges();
然后,如果我尝试访问导航属性,它将为空(即使在保存更改之后跟踪主对象)。 我尝试使用以下方法重新加载数据:
_context.Entry(entity).State = EntityState.Detached;
entity = _context.Set<MyEntity>().Where(e => e.Id == entity.Id).First();
我也尝试过使用 reload:
_context.Entry(entity).State = EntityState.Detached;
_context.Entry(entity).Reload();
不过,导航属性为空。
我在上下文配置中使用 UseLazyLoadingProxies。 获取导航属性的唯一方法是手动加载它:
_context.Entry(entity).Reference(e=> e.FirstObject ).Load()
有没有办法在 SaveChanges() 之后从 db 重新加载数据(丢弃所有缓存的数据)?
【问题讨论】:
您可以在实体的对象级别关闭缓存。检查此***.com/questions/15828811/… @marc_s 抱歉,我正在使用 EF Core,我已经更新了问题。 为什么在这种情况下使用分离实体?我很确定这是问题所在。 @SvyatoslavDanyliv 我正在使用分离来尝试从数据库重新加载数据。没有分离我有同样的行为。_context.Update(myEntity);
是个问题
【参考方案1】:
Reload
不检索相关数据(导航属性)。并且延迟加载不起作用,因为您正在使用 new
运算符创建实体实例,因此它没有被代理,这对于延迟加载代理至关重要。
为数据库分离和检索实体应该可以工作(在我的测试中它确实工作,不知道你为什么声称它不工作):
_context.Entry(entity).State = EntityState.Detached;
entity = _context.Set<MyEntity>().Where(e => e.Id == entity.Id).First();
但更好的选择是使用其中一种扩展方法(DbContext
或 DbSet<T>
)创建代理实例而不是 new
。唯一的缺点是您丢失了对象初始化器语法,但其他一切都可以工作。例如
var entity = _context.CreateProxy<MyEntity>(); // <--
entity.FirstId = 1;
entity.SecondId = 1;
//...data to update
_context.Update(entity);
_context.SaveChanges();
// verify it is working
var firstObject = entity.FirstObject;
var secondObject = entity.SecondObject;
Debug.Assert(firstObject != null && secondObject != null);
【讨论】:
我的工作就像一个魅力,谢谢!我不知道为什么从数据库重新加载数据在我的情况下不起作用......似乎 ef 保留了某种模型缓存。以上是关于Entity Framework Core 5 重新加载问题的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Core 5 - 递归结构错误
Entity Framework Core 5 重新加载问题
Entity Framework Core 中的日志记录与拦截器
Entity Framework Core中的日志记录与拦截器