在使用ADO.NET Entity Framework时,我发现自己一遍又一遍地重复这些代码。
VB:
' Load the thing if not already loaded. '
If Not Something.Thing.IsLoaded Then
Something.Thing.Load()
End If
C#:
// Load the thing if not already loaded.
if (!Something.Thing.IsLoaded)
{
Something.Thing.Load();
}
答案 0 :(得分:4)
根据您调用对象的方式(例如存储库),您可以在实体库集上使用“Include()”方法。
return EntitiesObject.Something.Include("Thing").Where(x=>x.ID == ID)
这样做会返回已加载“Thing”的对象。
这是一篇很好的文章:
答案 1 :(得分:4)
VS2010 beta中的EntityFramework版本在这方面非常友好。也就是说,如果您坚持使用没有延迟加载的版本,这种扩展方法可能会帮助您:
public static T EnsureLoaded<T>(this EntityReference<T> eRef) where T: class, IEntityWithRelationships
{
if (!eRef.IsLoaded)
eRef.Load();
return eRef.Value;
}
然后,假设您有User对象具有Contacts,您可以这样做:
Contact c = User.ContactReference.EnsureLoaded();
它仍然非常糟糕,但我发现如果声明一遍又一遍地写IsLoaded就更好了。
答案 2 :(得分:1)
如果您要加载7个客户的列表,然后为每个客户加载订单。
如果您是通过加载客户来完成的,那么循环每个客户,检查订单是否已加载然后加载它们。你将获得8(1 + 7)次数据库调用。
如果你在获得客户时使用了Include(“Orders”),那么就没有循环,没有if语句,只有一次调用数据库。
实体框架4将延迟加载。
答案 3 :(得分:1)
我赞同Shiraz所说的话。此外,我经常发现自己通过在部分类中包装EF生成的属性来实现延迟加载。这是一个例子:
public partial class Customer
{
public EntityCollection<Order> CustomerOrders
{
get
{
if (!Orders.IsLoaded)
Orders.Load();
return Orders;
}
}
}
在主叫方保存一些重复。
答案 4 :(得分:1)
这是完全正常和预期的。但它使性能优化变得困难。不幸的是,如果你想确保你的对象被加载,那么Include语句仍然需要在之后调用IsLoaded和Load。
答案 5 :(得分:1)
我为1-n关系扩展了tclem解决方案:
public static EntityCollection<T> EnsureLoaded<T>(this EntityCollection<T> eRef) where T : class, IEntityWithRelationships
{
if (!eRef.IsLoaded)
eRef.Load();
return eRef;
}