我正在尝试使用 DataServiceQuery 查询数据库中的单个实体。
我尝试加载的实体与我也想加载的其他实体的图表有关系。 MSDN 在此处和此处,我可以使用 DataServiceQuery.Expand 或 DataServiceContext.LoadProperty 加载引用的实体。
这对于我的实体的一级关系来说效果很好,但是我在加载关系的关系时遇到问题。
显然,我可以为所有二度关系调用 LoadProperty 并循环遍历所有二度集合,但我希望我可以在单个查询中急切地加载整个关系图。这可能吗?
编辑
实际上加载二阶关系毕竟不是那么明显。
以下代码失败(为了清晰起见,域模型已更改):
var context = DataServiceReference.DataServiceContextFactory.Create();
var customer = (from c in context.Customers.Expand("Orders")
where c.CustomerId.Equals(customerId)
select c).First();
foreach (var order in customer.Orders)
{
context.LoadProperty(order, "Products");
上面的最后一行抛出 InvalidOperationException:“上下文当前未跟踪实体。”。
我使用自我跟踪实体。这个错误可能与 STE 有关吗?
我将如何以任何方式加载二级关系?
解决方案编辑
事实证明,DataServiceQuery.Expand 与 ObjectQuery.Include 相比使用了不同的路径语法。前者使用斜杠作为路径分隔符,后者使用点。谁能解释为什么语法不一致以及在哪里可以找到扩展路径语法的文档?
I am trying to query a single entity in a database with a DataServiceQuery.
The entity I am trying to load has relations to a graph of other entities that I want to load as well. MSDN describes here and here that I can load my referred entities using either DataServiceQuery<TElement>.Expand or DataServiceContext.LoadProperty.
This works fine for first degree relations of my entity, but I have a problem loading relations of relations.
Obviously I could call LoadProperty for all second degree relations and loop through all second degree collections, but I was hoping that I could eager load the whole relation graph in a single query. Is that possible?
Edit
Actually loading the second degree relations is not that obvious after all.
The following code fails (domain model changed for clarity):
var context = DataServiceReference.DataServiceContextFactory.Create();
var customer = (from c in context.Customers.Expand("Orders")
where c.CustomerId.Equals(customerId)
select c).First();
foreach (var order in customer.Orders)
{
context.LoadProperty(order, "Products");
The last line above throws InvalidOperationException: "The context is not currently tracking the entity.".
I use self-tracking-entities. Could this error be related to STE?
How would I load second degree relations in any way?
Solution edit
It turns out that DataServiceQuery<TElement>.Expand uses a different path syntax compared to ObjectQuery<T>.Include. The former uses slash as path separator the latter uses dot. Can anyone explain why the syntax is inconsistent and where I can find documentation of the Expand path syntax?
发布评论
评论(1)
DataServiceContextFactory 是您自己的类,对吗? (因为这不是您通常实例化 DataServiceContext 的方式)。假设它最终创建一个普通的 DataServiceContext 实例,那么预先加载多个级别的方法就是在 Expand 调用中指定多个级别。例如:
context.Customers.Expand("订单/产品")
将向您退回所有客户、他们的订单以及这些订单的所有产品。
为了使 LoadProperty 正常工作,请确保在 DataServiceContext 上将属性 MergeOption 设置为允许跟踪的选项之一。
请注意,客户端跟踪与服务器端 EF 跟踪无关(从技术上讲,它是单独计算机上的单独代码)。
您可以通过尝试调用来验证上下文是否跟踪有问题的实体
context.GetEntityDescriptor(myEntityInstance)
如果它返回非空,则上下文正在跟踪实体,并且 LoadProperty 应该可以工作。
The DataServiceContextFactory is your own class, right? (since that's not how you typically instantiate a DataServiceContext). Assuming it ends up creating a normal DataServiceContext instance then the way to eager load multiple levels is just to specify the multiple levels in you Expand call. So for example:
context.Customers.Expand("Orders/Products")
Will return you all customers, their orders and all the products for those orders.
For LoadProperty to work, please make sure that on your DataServiceContext the property MergeOption is set to one of the options which allow tracking.
Note that the client side tracking has nothing to do with the server side EF tracking (it's a separate code on a separate machine technically).
You can verify that the context tracks the entity in question by trying to call
context.GetEntityDescriptor(myEntityInstance)
If it returns non-null, the context is tracking the entity and LoadProperty should work.