实体框架检索导航属性
本文关键字:属性 导航 检索 框架 实体 | 更新日期: 2023-09-27 17:50:48
我正在使用EF 5,我已经启用了延迟加载。当我从数据库中检索实体时,它可以完美地工作。
这是我的问题。我有一个通用的存储库来执行数据库操作。 public int Update(T t) //Update method implemented at repository layer
{
dbSet.Attach(t);
context.Entry(t).State = EntityState.Modified;
return context.SaveChanges();
}
public T Update(T t, int id) //This Method calls the above method to
{
if (Update(t) > 0)
{
//Now entity is updated so retrieve the entity from the database.
return Get(id); //This line of code doesn't return entity with reference. It does return the updated entity.
}
return null;
}
现在,当我使用主键查询实体以获得更新的实体时,它会给我更新的实体,但没有任何引用属性。我不能在这里使用延迟加载,因为它会抛出一个异常。
更新实体后,我注意到dbSet。Local具有更新后的实体。所以我试图清除之前,我检索更新的实体,但没有运气。我还尝试通过上下文重新加载实体,但它不会重新加载导航属性。我不能使用引用属性,因为我正在使用通用存储库。我能完成的唯一方法是处置并创建context和dbset的新实例。
我想返回已更新的实体,并填充关系属性。有没有人有好的解决办法?
我启用了延迟加载
我正在附加POCO实体
我从你的评论中假设,在你的应用程序的某个地方,你正在实例化你的实体,如new MyEntity()
,这样的延迟加载将不起作用,因为它不是代理POCO。
考虑到您已经启用了延迟加载,您想要做的最简单的方法是使用代理poco。也就是说,使用下面的代码实例化一个实体,无论它在哪里:
MyEntity entity = MyContext.MyEntities.Create();
延迟加载应该为您工作。如果您不想这样做或这样做不起作用,那么最好的选择是从数据库中提取现有实体(作为动态代理)并从POCO填充。所以在你的仓库更新方法中:
编辑
我应该注意,也可以做到这一点,而不需要往返于数据库。看到评论。
public T Update(T poco)
{
//get the entity from db
T proxyPoco = context.Set<T>().Find(id);
//alternatively just create the proxy, set the id and attach.
//no db retrieval.
//T proxyPoco = context.Set<T>.Create();
//proxyPoco.Id = poco.Id;
//context.Set<T>.Attach(proxyPoco);
if(proxyPoco == null)
{
//throw an exception or handle case where the entity is not found.
//unecessary if using alternative above.
}
else
{
//set the proxy poco values using your original poco
context.Entry<T>(proxyPoco).CurrentValues.SetValues(poco);
}
context.SaveChanges();
return proxyPoco;
}
因为您返回了代理POCO,所以延迟加载应该可以工作。其他不太理想的选项是:
- 丢弃上下文并重新获取实体。
- 使用反射显式加载实体的引用和集合。
SaveChanges返回一个int
。如果您想要恢复实体,请尝试:
public T Update(T t)
{
dbSet.Attach(t);
context.Entry(t).State = EntityState.Modified;
context.SaveChanges();
return t;
}