【问题标题】:Breeze does not expand a navigation propertyBreeze 不扩展导航属性
【发布时间】:2012-12-06 06:13:32
【问题描述】:

我的单页应用程序中有一个 Breeze 数据服务(又名 datacontext)。我想从 WebAPI 控制器获取运行列表以及每次运行的 OutlineItems 列表。

控制器正在使用 BreezeController 上的此方法返回带有子 OutlineItems 的打开运行列表。

[AcceptVerbs("GET")]
public IQueryable<Run> Runs()
{
return _contextProvider.Context.Runs
    .Include("RunOutlineItems")
    .AsQueryable()
    .Where(r => r.RunStatusId < 4);    // 4 is the cutoff for open items             

}

这是数据模型。

namespace PilotPlantBreeze
{
    public class Run
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Rundate { get; set; }
        public DateTime? RunStart { get; set; }
        public int MachineId { get; set; }
        public int ProductId { get; set; }
        public int RunStatusId { get; set; }
        public string Comments { get; set; }

        // Nav props
        public IList<OutlineItem> RunOutlineItems { get; set; }
    }
}       

当我查看来自 WebAPI 请求的响应数据时,RunOutlineItems 列表位于 JSON 中。以其中一项为例:

{
    "$id":"27",
    "$type":"PilotPlantBreeze.OutlineItem,PilotPlantBreeze.Model",
    "Id":22,
    "RunId":5,
    "TankId":4,
    "OutlineTopicId":1,
    "OutlineDescriptionId":9,
    "PersonId":1,
    "Value":"23"
}

这是我从 WebAPI 获取数据的客户端 JavaScript 代码。 为清楚起见,省略了错误检查和本地缓存检查。

var getRuns = function () {
    // The EntityQuery is defined at the beginning of the dataservice
    //  Here I am asking for a query on the server.  Note the .expand 
    //  which is supposed to avoid lazy loading.  Lazy loading is turned off 
    //  on the WebAPI already.
    var query = EntityQuery
    .from("Runs")
    .expand("RunOutlineItems")
    .orderBy("rundate");

    // The manager is defined at the beginning of the dataservice
    //  Here I am asking the manager to execute the query with a promise
    return manager.executeQuery(query)
    .then(runsQuerySucceeded)
    .fail(runsQueryFailed);

    // The promise does not fail, but I would put an error in here if it ever does
    function runsQueryFailed(data) {
    }
    // When the promise succeeds, the data parameter is the JSON from the WebAPI
    function runsQuerySucceeded(data) {
        //
        // When I stop the debugger here data.results holds the entities, but
        //  the child entities for the RunOutlineItems is an observableArray with 
        //  nothing in it.
        //
        app.vm.runs.runs(data.results);
    }
};

所以我的问题是如何将子项放入我的 viewModel。我有一个解决方法,它在服务器上对 WebAPI 的单独调用中获取子项,并使用自定义 ko.bindHandler 处理它们,但是让导航技术工作会很方便。

【问题讨论】:

  • 如果它回答了您的问题,请检查 Jay 的回答下的复选标记。这样我们就知道问题已经解决了。如果它没有关闭,请告诉我们,以便我们跟进。谢谢。

标签: jquery knockout.js asp.net-web-api entity-framework-5 breeze


【解决方案1】:

您不应该同时需要“包含”(服务器端)和扩展(客户端);任何一个都应该做到这一点。

所以我会不理会客户端查询并将服务器端查询修改为:

[AcceptVerbs("GET")]
public IQueryable<Run> Runs() {
    return _contextProvider.Context.Runs
      .Where(r => r.RunStatusId < 4);    // 4 is the cutoff for open items             

}

请注意,AsQueryable() 也已消失。

如果这不起作用,请回帖。

【讨论】:

  • 此更改仍然无效。我按照您的建议修改了服务器代码: var x = _contextProvider.Context.Runs .Where(r => r.RunStatusId
  • 让我们尝试一些小步骤。将包含返回到服务器上的查询并测试 EF 结果是否包含子项。希望您的 EF 印记足够清晰,以便您可以在调试服务器代码时在 _contextProvider.Context 中验证这一点。下一步是通过网络检查 JSON;您应该在响应正文中看到它们(在其调试工具中使用 Fiddler 或浏览器网络观察程序)。我们等待您的发现。
  • 我尝试了这些步骤。我将服务器上的返回值分配给一个 var 和一个 IQueryable,并且在使用调试器检查后,发现 Runs 确实包含子 RunOutlineItem 是列表。我还可以看到 RunOutlineItem(s) 在线路上的响应正文 JSON 中。我可以在 F12 中使用 IE 和 Chrome 中的开发者工具看到它们。
  • 当promise成功时,在函数runsQuerySucceeded(data) { window.app.vm.runs.runs(data.results); };,我停止调试器。 data.XHR.responseText 包含 RunOutlineItems,但 data.results[0].runOutlineItems() 的值为 []。 data.results[1]...[n] 也是如此
  • 我不知道它是否适用于 WebAPI - 查看我的类似问题:stackoverflow.com/questions/17399906/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多