我正在试图弄清楚如何使用knockout和breeze设置父子选择元素。这就是我所拥有的,但它不起作用。我做错了什么?
这是模型
ModelYear.cs(Parent)
public class ModelYear
{
public ModelYear()
{
Vehicles = new List<Vehicle>();
}
public int Id { get; set; }
public string Year { get; set; }
public virtual ICollection<Vehicle> Vehicles { get; set; }
}
Vehicle.cs(Child)
public class Vehicle
{
public int Id { get; set; }
public string Title { get; set; }
}
TestController.cs
[BreezeController]
public class TestController : ApiController
{
private readonly EFContextProvider<TestContext> contextProvider = new EFContextProvider<TestContext>();
[HttpGet]
public string MetaData()
{
return contextProvider.Metadata();
}
[HttpGet]
public IQueryable<ModelYear> ModelYears()
{
return contextProvider.Context.ModelYears;
}
}
dataService.js
app.dataService = (function (breeze) {
var serviceName = 'breeze/test';
var manager = new breeze.EntityManager(serviceName);
return {
getModelYears: getModelYears
};
function getModelYears() {
var query = breeze.EntityQuery.from("ModelYears").expand("Vehicles");
return manager.executeQuery(query);
}
})(breeze);
viewModel.js
app.viewModel = (function (dataService) {
var vm = {
years: ko.observableArray(),
selectedYear: ko.observable()
};
initVm();
return vm;
function initVm() {
getYears();
}
function getYears() {
dataService.getModelYears()
.then(querySucceeded)
.fail(queryFailed);
}
function querySucceeded(data) {
vm.years(data.results);
}
function queryFailed(error) {
alert("Query failed. " + error.message);
}
})(app.dataService);
ko.applyBindings(app.viewModel);
当我在querySucceeded方法中放置一个断点并检查data参数时,results变量是一个只有Id和Year knockout observable的对象数组,上面没有Vehicles数组。然而,当我检查网络流量时,车辆阵列就在那里。我不知道还能做什么。
以下是从服务器返回的元数据:
{
"schema":{
"namespace":"BreezeTesting.Models",
"alias":"Self",
"annotation:UseStrongSpatialTypes":"false",
"xmlns:annotation":"http://schemas.microsoft.com/ado/2009/02/edm/annotation",
"xmlns":"http://schemas.microsoft.com/ado/2009/11/edm",
"cSpaceOSpaceMapping":"[[\"BreezeTesting.Models.ModelYear\",\"BreezeTesting.Models.ModelYear\"],[\"BreezeTesting.Models.Vehicle\",\"BreezeTesting.Models.Vehicle\"]]",
"entityType":[
{
"name":"ModelYear",
"key":{
"propertyRef":{
"name":"Id"
}
},
"property":[
{
"name":"Id",
"type":"Edm.Int32",
"nullable":"false",
"annotation:StoreGeneratedPattern":"Identity"
},
{
"name":"Year",
"type":"Edm.String",
"maxLength":"Max",
"fixedLength":"false",
"unicode":"true"
}
],
"navigationProperty":{
"name":"Vehicles",
"relationship":"Self.ModelYear_Vehicles",
"fromRole":"ModelYear_Vehicles_Source",
"toRole":"ModelYear_Vehicles_Target"
}
},
{
"name":"Vehicle",
"key":{
"propertyRef":{
"name":"Id"
}
},
"property":[
{
"name":"Id",
"type":"Edm.Int32",
"nullable":"false",
"annotation:StoreGeneratedPattern":"Identity"
},
{
"name":"Title",
"type":"Edm.String",
"maxLength":"Max",
"fixedLength":"false",
"unicode":"true"
}
]
}
],
"association":{
"name":"ModelYear_Vehicles",
"end":[
{
"role":"ModelYear_Vehicles_Source",
"type":"Edm.Self.ModelYear",
"multiplicity":"0..1"
},
{
"role":"ModelYear_Vehicles_Target",
"type":"Edm.Self.Vehicle",
"multiplicity":"*"
}
]
},
"entityContainer":{
"name":"TestContext",
"entitySet":[
{
"name":"ModelYears",
"entityType":"Self.ModelYear"
},
{
"name":"Vehicles",
"entityType":"Self.Vehicle"
}
],
"associationSet":{
"name":"ModelYear_Vehicles",
"association":"Self.ModelYear_Vehicles",
"end":[
{
"role":"ModelYear_Vehicles_Source",
"entitySet":"ModelYears"
},
{
"role":"ModelYear_Vehicles_Target",
"entitySet":"Vehicles"
}
]
}
}
}
}
以下是从服务器返回的数据。
[
{
"$id":"1",
"$type":"BreezeTesting.Models.ModelYear, BreezeTesting",
"Id":1,
"Year":"2012",
"Vehicles":[
{
"$id":"2",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":1,
"Title":"CTS Sport Sedan"
},
{
"$id":"3",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":2,
"Title":"CTS Coupe"
},
{
"$id":"4",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":3,
"Title":"Escalade ESV"
},
{
"$id":"5",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":4,
"Title":"SRX Crossover"
}
]
},
{
"$id":"6",
"$type":"BreezeTesting.Models.ModelYear, BreezeTesting",
"Id":2,
"Year":"2013",
"Vehicles":[
{
"$id":"7",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":5,
"Title":"XTS Sedan"
},
{
"$id":"8",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":6,
"Title":"ATS Sedan"
},
{
"$id":"9",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":7,
"Title":"CTS Sport Sedan"
}
]
},
{
"$id":"10",
"$type":"BreezeTesting.Models.ModelYear, BreezeTesting",
"Id":3,
"Year":"2014",
"Vehicles":[
{
"$id":"11",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":8,
"Title":"XTS Sedan"
},
{
"$id":"12",
"$type":"BreezeTesting.Models.Vehicle, BreezeTesting",
"Id":9,
"Title":"SRX Crossover"
}
]
}
]
答案 0 :(得分:2)
在探索此类问题时,请按照“Query Result Debugging”中的步骤操作。它应该引导你到达轮子脱落的位置。
碰巧,这种情况的原因很明显(对我来说:-)。您的Vehicle
类型缺少指向父Vehicle.ModelYearId
类型的ModelYear
等FK属性。这个事实在导航属性没有FK的元数据中也很明显。
实体框架容忍这就是为什么你在原始数据中看到车辆的原因。在幕后,它推断并使用数据库中Vehicles表中实际FK列的名称。
你也可以做一些EF映射,因为这种关联是单向的;您没有从孩子(
Vehicle
)导航回父母(ModelYear
)。
然而,客户端上的Breeze无法在车辆数据中没有FK值的情况下维护ModelYear.Vehicles
集合。
如果您愿意,可以从服务器发送对象图。但Breeze无法自行组装这些图表或在客户端保持原样。这就是我们说Breeze要求FK维护导航属性的原因。
答案 1 :(得分:0)
我有同样的问题,detail in this thread。 实际上我需要添加两个属性,一个用于FK,一个用于父对象。仅FK属性不起作用。