设置父子选择元素,在微风和淘汰赛中加入急切加载

时间:2013-12-16 21:31:00

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

我正在试图弄清楚如何使用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"
         }
      ]
   }
]

2 个答案:

答案 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属性不起作用。