【问题标题】:Loading recursive OData (WCF Data Service)加载递归 OData(WCF 数据服务)
【发布时间】: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


    【解决方案1】:

    我不确定您为什么需要递归 URI,但从 OData 的角度来看,此处由 LoadProperty() 生成的 URL 是正确的。

    在 OData 世界中,每个实体都有一个唯一的实体 ID。例如,/api/Nodes(123)/api/Nodes(234) 是两个实体的实体 ID。所以查询/api/Nodes(123)/SubNodes(234) 确实是针对实体/api/Nodes(234)。当你请求/api/Nodes(123)/SubNodes(234)/SubNodes 时,它与/api/Nodes(234)/SubNodes 相同。所以 LoadProperty 在这里做的是正确的事情。

    如果您仍需要构建递归 URI,则必须自己构建它。

    【讨论】:

    • 好的。我知道了。那么问题是 OData-feed 中的设计问题,因为 /api/Nodes 不返回系统中的所有节点,只返回根节点。要获取系统中的所有节点,您必须递归整个树。
    • @MathiasR 如果是这种情况,您可能希望将节点放在不同的实体集中。例如/api/RootNodes, /api/OtherNodes
    【解决方案2】:

    根据 OData 规范 /api/Nodes 返回节点类型的所有实体。 因此,/api/Nodes(234) 将返回节点 #234。 您需要开发一个自定义方法来返回根节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多