实体框架检索导航属性

时间:2013-01-06 22:37:14

标签: c# asp.net entity-framework asp.net-mvc-4

我正在使用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。

我想返回已填充关系属性的更新实体。有没有人有一个好的解决方案。

2 个答案:

答案 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延迟加载应该工作。 其他不太理想的选择是:

  1. 放弃上下文并再次获取实体。
  2. 使用反射显式加载该实体的引用和集合。