在EF4中,是否有一种相对简单的方法来急切加载实体的所有相关实体?我认为扩展方法对此非常完美。我有一个场景,我正在使用POCO,其中一个实体具有其他实体的多个导航属性,而这些实体又有自己的导航属性。不用说,很多循环和加载都急切地加载一切。我想在调用扩展方法时加载并准备好所有属性,这样我就可以关闭LazyLoading。
类似的东西:
using(var context = new MyEntities())
{
var widget = context.Widgets.FirstOrDefault();
widget.RecursivelyLoadAllPropertiesForMe() // magical extension method I wished existed
}
答案 0 :(得分:2)
渴望加载始终是明确的 - 没有自动化。您必须为要加载的所有关系定义包含。如果你不这样做,你几乎总是会使用针对每个关系的新查询来解决问题。
您的扩展方法必须使用:
((EntityCollection<...>)entity.NavigationCollection).Load();
如果您需要加载子关系,您也可以致电:
((EntityCollection<...>)entity.NavigationCollection).CreateSourceQuery()
.Include(...)
.Execute();
但是,对Load
或Execute
的每次调用仍然会为数据库创建一个新查询,您必须编写一个代码来执行这些调用。此外,您必须拥有代理实体才能将公共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; }
}