我正在使用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;
}
现在,当我使用主键查询实体以获取更新的实体时,它会为我提供更新的实体,但是没有任何引用属性。我不能在这里使用Lazy加载,因为它会引发异常。
更新enttity后,我注意到dbSet.Local有更新的实体。所以我试图清除之前我检索更新的实体但没有运气。我也尝试通过上下文重新加载实体,但它不重新加载导航属性。我不能使用Reference属性,因为我使用通用存储库。 我能完成的唯一方法是配置并创建新的上下文实例和dbset。
我想返回已填充关系属性的更新实体。有没有人有一个好的解决方案。
答案 0 :(得分:1)
SaveChanges返回int
。你想要实体回来,试试这个:
public T Update(T t)
{
dbSet.Attach(t);
context.Entry(t).State = EntityState.Modified;
context.SaveChanges();
return t;
}
答案 1 :(得分:1)
我启用了延迟加载
我正在附加POCO实体
我假设您的应用程序中的某个地方正在实例化您的实体new MyEntity()
,因此懒惰加载将无效,因为它不是代理POCO。
考虑到你说启用了延迟加载,最简单的方法是做你正在尝试做的事情,就是使用代理POCO。这是使用以下实例化实体,无论在哪里:
MyEntity entity = MyContext.MyEntities.Create();
延迟加载应该适合你。如果您不想这样做或者这不起作用,那么最好的选择是从数据库中提取现有实体(作为动态代理)并从POCO中填充。所以在您的存储库更新方法中:
修改强>
我应该注意,也可以在没有往返db的情况下这样做。见评论。
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延迟加载应该工作。 其他不太理想的选择是: