1

我的單頁應用程序中有一個Breeze dataservice(又名datacontext)。我想從WebAPI控制器獲得一個運行列表以及每個運行的OutlineItems列表。Breeze不擴展導航屬性

控制器使用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" 
} 

這是我的客戶端JavaScript代碼從WebAPI獲取數據。 錯誤檢查和本地緩存檢查被省略以清楚起見。

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處理它們,但導航技術可以很方便地工作。

+0

如果Jay回答你的問題,請選中Jay的答案。這樣我們就會知道問題已經結束。如果它沒有關閉,請告訴我們,以便我們跟進。謝謝。 – Ward

回答

2

您不應該同時需要'include'(服務器端)和expand(客戶端);任何一個人都應該這樣做。

所以我獨自離開你的客戶端查詢和修改服務器端查詢到眼前這個:

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

} 

注意,AsQueryable已()走了爲好。

如果這不起作用,請回復。

+0

此更改仍不起作用。我按照以下建議修改了服務器代碼: var x = _contextProvider.Context.Runs 。Where(r => r.RunStatusId <4); return x; 當我看着x,這是正確的類型,RunOutlineItems屬性爲null。不用說,客戶端上的數組也是空的。 所以我想我需要包含。也許在客戶端,我需要使用EntityQuery.fromEntityNavigation 來創建一個新的查詢並執行該操作,以便在獲取特定的Run實體時從服務器中提取導航項。 尼克 – bizcad

+0

讓我們試試嬰兒的步驟。將包含放回服務器上的查詢並測試EF結果是否包含子項。希望您的EF印章足夠清晰,以便您可以在調試服務器代碼時在'_contextProvider.Context'中驗證這一點。下一步是檢查電線上的JSON;您應該在響應主體中看到它們(使用Fiddler或其調試工具中的瀏覽器網絡觀察器)。我們等待您的發現。 – Ward

+0

我試過這些步驟。我將服務器上的返回值分配給var和IQueryable ,並且在使用調試器進行檢查時發現,Runs確實包含子RunOutlineItem是List。我還可以看到RunOutlineItem(s)在線路中的響應正文JSON中。我可以在Chrome中使用IE和Developer Tools在F12中看到它們。 – bizcad