Entity Framework 3.5 - 如何加载孩子
Posted
技术标签:
【中文标题】Entity Framework 3.5 - 如何加载孩子【英文标题】:Entity Framework 3.5 - How to load children 【发布时间】:2010-11-25 08:54:51 【问题描述】:我的问题可能很简单,你如何加载子类/子类。我找不到任何“负载”或类似的东西来让上下文加载孩子。
上下文类是ObjectContext类型,见下文:
public partial class RTIPricingEntities : global::System.Data.Objects.ObjectContext
产品
Product.ModifiedByUser(加载产品时如何加载这个类??)
Product.Category(加载产品时如何加载分类?)
【问题讨论】:
这是我如何加载数据的示例: 也许我应该提到我正在为 silverlight 应用程序编写此代码。这是通过域服务。 RTIPricingContext _context = new RTIPricingContext(); LoadOperation我注意到 Craig 的上述解决方案没有同时加载 ModifiedByUser 和 Category。它只加载最后一个对象集合,在这种情况下是“类别”。
var q = from p in Context.Products
.Include("ModifiedByUser")
.Include("Category")
select p;
但是,如果您交换订单以使其成为.Include("Category").Include("ModifiedByUser")
,则加载ModifiedByUser
。奇怪的是,两个对象集合的IsLoaded
属性都将显示“true”,但是第一个对象集合的计数始终为零。不知道为什么会这样。
【讨论】:
【参考方案2】:您可以预先加载:
var q = from p in Context.Products
.Include("ModifiedByUser")
.Include("Category")
select p;
...或项目:
var q = from p in Context.Products
select new
Id = p.Id,
Name = p.Name
ModifiedByUserName = p.ModifiedByUser.Name,
CategoryName = p.Category.Name
投影的优点是您只获得所需的数据,而不是每个引用实体的全部。急切加载的优点是返回的实体会进行更改跟踪。为手头的问题选择正确的技术。
更新
是的,提及您正在使用 RIA 服务 很重要。我想你也在客户内部工作。这让事情完全与众不同。
在 RIA 服务中,确保返回初始加载时所需的整个实体图非常重要。您不想在实体上调用 .Load() 之类的东西,因为这对服务器来说是另一个热点,这对性能不利。例如,如果您在 Silverlight 客户端并从服务器请求实例列表,并且它们的相关属性尚未具体化,则为时已晚。此外,Include 不能在 Silverlight 客户端中工作。因此,RIA 服务具有服务器端工具,您可以使用它来确保您最初返回正确的、完全具体化的对象图。
您需要做的是在您的 RIA 服务服务器中使用 IncludeAttribute。您可以创建一个“伙伴”元数据类来使用 [Include] 来装饰您的实体模型。 the RIA Services overview document, section 4.8中有例子。
【讨论】:
你好,我不知道我们是否有相同的版本,但是在我编码时这两个选项都不可能。没有可用的“.Include”,只有“Intersect”..我使用以“ObjectContext”作为其基类的实体框架派生实体..当我进行项目时,智能感知中没有属性可供我设置.. Include 是 ObjectQuery使用.Include()
就像许多其他人所建议的那样是实现您需要的好方法。
但是,有时您可能需要稍后“重新加载”一些您没有“包含”的内容,或者您只是有时需要,因此在许多情况下放置 Include 语句可能会浪费计算周期。
如果是像“Product.Category”这样的单一关系(其中 Product.Category 是您从产品到类别的导航属性),您很可能还有一个“Product.CategoryReference”元素。您可以检查它是否已加载,如果没有,您可以“按需”加载它:
if(!Product.CategoryReference.IsLoaded)
Product.CategoryReference.Load();
现在您引用的“类别”应该在内存中并且可以使用了。
如果您有一个导航属性引用了一组事物(例如,产品的“部件”),您可以直接在导航属性上执行相同的操作:
if(!Product.Parts.IsLoaded)
Product.Parts.Load();
如果您没有将它们“包含”到您的 EF 查询中,这对于“按需加载”单个或集合类型导航属性可能是一种有用的技术。
马克
【讨论】:
谢谢大家,我意识到我无法实施许多提议的解决方案的原因是,一旦被 Silverlight 的域服务转换,上下文就不同了。在实体框架数据模型背后的代码中,我可以实现您的所有解决方案,而我刚刚发现了这一点。但多亏了你的帮助,我知道问题一定是我找错地方了……【参考方案4】:您可以使用System.Data.Objects.ObjectQuery 的Include() 方法。此方法指定要包含在查询结果中的相关对象,并且对 Include() 的调用可以链接在一起以加载多个相关对象。
例如,要加载 ModifiedByUser 和 Category,您可以使用如下查询:
var q = from p in context.Products.Include("ModifiedByUser").Include("Category")
select p;
如果您的 Category 实体也有一个您想要加载的 ModifiedByUser 实体,您可以使用如下查询:
var q = from p in context.Products
.Include("ModifiedByUser")
.Include("Category.ModifiedByUser")
select p;
有关更多示例,请参阅 MSDN 上的 Shaping Query Results。
【讨论】:
我经常看到这个解决方案,所以我必须做一些与其他人完全不同的事情。基本上,我使用的是实体框架生成的数据模型中的上下文。我有最新的.Net。没有“包含”可用。你在这个例子中使用 dbml/linq 吗?我想这就是为什么它不同......以上是关于Entity Framework 3.5 - 如何加载孩子的主要内容,如果未能解决你的问题,请参考以下文章
从哪里开始 .NET Entity Framework 和 ORM?
如何迁移 .NET Framework 应用程序? [3.5 到 2.0]