【发布时间】:2014-03-09 17:29:34
【问题描述】:
我有一个 wcf 数据服务,它有一个返回以下实体的服务“节点”。
[DataServiceKey("NodeId")]
public class Node
{
public int NodeId { get; set; }
public IQueryable<Node> SubNodes
{
get { return new NodeRepository().GetNodes(this.NodeId); }
}
}
这给了我一个完全递归的 OData 服务。我得到所有带有http://www.test.com/api/Nodes的根节点,带有http://www.test.com/api/Nodes(123)的单个节点,带有http://www.test.com/api/Nodes(123)/SubNodes的子节点,带有http://www.test.com/api/Nodes(123)/SubNodes(234)的单个子节点,带有http://www.test.com/api/Nodes(123)/SubNodes(234)/SubNodes的子节点的子节点等等。
问题是如何在代码中使用这些数据。
我可以使用
var context = new MyServiceV1.TheServiceContext(new Uri(dataUrl));
var nodes = context.Nodes;
获取第一级节点。然后,如果我将上下文和我的节点传递给这个方法,我可以获得第一级节点的子节点。
private void RecurseNodes(TheServiceContext context, IEnumerable<Node> nodes)
{
foreach (var node in nodes)
{
var subNodes = dataContext.LoadProperty(node, "SubNodes") as QueryOperationResponse<Node>;
RecurseNodes(dataContext, subNodes);
}
}
上面的 LoadProperty 调用将生成正确的 url (/api/Nodes(123)/SubNodes),但是当它尝试加载下一级的子节点(即 id 为 234 的节点)时,它使用 url /api/节点(234)/子节点。它应该使用的是/api/Nodes(123)/SubNodes(234)/SubNodes。
我必须自己开始生成 url,还是我可以指示 datacontext 来完成这个?
解决方案:问题出在 OData-feed 中,因为 /api/Nodes 不返回所有节点,只返回根节点。这就是我在不接触 OData-feed 的情况下解决它的方法:
private void RecurseNodes(IEnumerable<Node> nodes, NCContentServiceContext dataContext, string baseUrl)
{
foreach (var node in nodes)
{
var url = baseUrl + "(" + node.NodeId + ")/SubNodes";
var subNodes = dataContext.Execute<Node>(new Uri(url, UriKind.Relative)).ToList();
RecurseNodes(subNodes, dataContext, url);
}
}
调用者是
var context = new MyServiceV1.TheServiceContext(new Uri(dataUrl));
RecurseNodes(context.Nodes, context, "/Nodes");
【问题讨论】:
标签: recursion wcf-data-services