EF4 - 加载所有相关实体的简便方法?

时间:2011-12-02 21:29:47

标签: entity-framework poco

在EF4中,是否有一种相对简单的方法来急切加载实体的所有相关实体?我认为扩展方法对此非常完美。我有一个场景,我正在使用POCO,其中一个实体具有其他实体的多个导航属性,而这些实体又有自己的导航属性。不用说,很多循环和加载都急切地加载一切。我想在调用扩展方法时加载并准备好所有属性,这样我就可以关闭LazyLoading。

类似的东西:

using(var context = new MyEntities())
{
   var widget = context.Widgets.FirstOrDefault();
   widget.RecursivelyLoadAllPropertiesForMe() // magical extension method I wished existed
}

4 个答案:

答案 0 :(得分:2)

渴望加载始终是明确的 - 没有自动化。您必须为要加载的所有关系定义包含。如果你不这样做,你几乎总是会使用针对每个关系的新查询来解决问题。

您的扩展方法必须使用:

((EntityCollection<...>)entity.NavigationCollection).Load();

如果您需要加载子关系,您也可以致电:

((EntityCollection<...>)entity.NavigationCollection).CreateSourceQuery()
                                                    .Include(...)
                                                    .Execute();

但是,对LoadExecute的每次调用仍然会为数据库创建一个新查询,您必须编写一个代码来执行这些调用。此外,您必须拥有代理实体才能将公共ICollection<...>转换为EntityCollection<...>,并且必须使用常见的预先加载来加载所有简单的导航属性(而不是集合)。

答案 1 :(得分:2)

这是我提出的扩展方法:

public static void LoadAllProperties<T>(this T entity, ObjectContext context)
{
    Type type = entity.GetType();
    context.Refresh(RefreshMode.ClientWins, entity);
    foreach (var property in type.GetProperties())
    {
        if (property.PropertyType.Name.StartsWith("ICollection"))
        {
            context.LoadProperty(entity, property.Name);
            var itemCollection = property.GetValue(entity, null) as IEnumerable;
            foreach (object item in itemCollection)
            {
                item.LoadAllProperties(context);
            }
        }
    }
}

此方法首先通过从上下文刷新实体来加载正常的实体属性值。然后,它遍历每个属性,查找作为集合的导航属性,并递归加载集合中的每个项目。这适用于我需要的东西,并且不要求您使用代理或包含。

用法:

using(var context = new MyEntities())
{
    context.ContextOptions.ProxyCreationEnabled = false;
    var widget = context.Widgets.FirstOrDefault();  
    widget.LoadAllProperties(context);
}

答案 2 :(得分:-1)

是的!去吧:

widget.Load()

或者如果你去了:

var widget = context.Widgets.FirstOrDefault().Include("SomeRelatedEntities").Include("OtherRelatedEntities");
你不需要!

答案 3 :(得分:-1)

第1步                     context.DataContext.ContextOptions.ProxyCreationEnabled = true;                     context.DataContext.ContextOptions.LazyLoadingEnabled = true;

第2步                    将虚拟关键字添加到导航属性

  public class BankBranche 
   {
    public int Id { get; set; }

    public string Name { get; set; }

    public string Code { get; set; }

    public int BankId { get; set; }

    public virtual Address Address { get; set; }

    public virtual Bank Bank { get; set; }

}