【问题标题】:Breeze 1.4.6 + Web API 2 OData - Navigation properties missingBreeze 1.4.6 + Web API 2 OData - 缺少导航属性
【发布时间】:2013-12-25 23:30:38
【问题描述】:

在撰写本文时,我正在尝试将最新版本的 Breeze (1.4.6) 与 Web API 2 (ODataController) 一起使用。我的问题是 Breeze 的结果缺少导航属性。

考虑以下几点:

public class Country : EntityBase<long>
{
    public Country()
    {
        Provinces = new List<Province>();
    }

    [Required]
    [StringLength(256)]
    public string Name { get; set; }

    [Required]
    [StringLength(3)]
    public string Abbreviation { get; set; }

    // Navigation Properties

    [InverseProperty("Country")]
    public virtual ICollection<Province> Provinces { get; set; }
}

public class Province : EntityBase<long>
{
    [Required]
    [StringLength(256)]
    public string Name { get; set; }

    [Required]
    [StringLength(3)]
    public string Abbreviation { get; set; }

    public long CountryId { get; set; }

    [ForeignKey("CountryId")]
    [InverseProperty("Provinces")]
    public virtual Country Country { get; set; }
}

然后我使用 VS 2013 为 Country 搭建了一个 ODataController 并确保我的 WebApiConfig 已正确更新:

var builder = new ODataConventionModelBuilder();
builder.EntitySet<Country>("Countries");
builder.EntitySet<Province>("Provinces");
builder.Namespace = "MyNamespace.Models";

var batchHandler = new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer);
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel(), batchHandler);

此时我能够成功地对我的数据运行查询。

http://mysite.local/Api/odata/Countries?$expand=省

这会返回你所期望的:

 {
  "odata.metadata":"http://mysite.local/Api/odata/$metadata#Countries","value":[
    {
      "Provinces":[
        {
          "Name":"Alberta","Abbreviation":"AB","CountryId":"1","Id":"1"
        },{
          "Name":"British Columbia","Abbreviation":"BC","CountryId":"1","Id":"2"
        },{
          "Name":"Manitoba","Abbreviation":"MB","CountryId":"1","Id":"3"
        },{
          "Name":"New Brunswick","Abbreviation":"NB","CountryId":"1","Id":"4"
        }
        // edited for brevity
      ],"Name":"Canada","Abbreviation":"CA","Id":"1"
  }
}

现在我准备开始在客户端上使用这些数据。我连接了 datajs/Breeze 并将微风配置为使用 OData。这是我用来配置和创建微风管理器的内容:

    function configureBreezeManager() {
        breeze.config.initializeAdapterInstances({
            dataService: 'OData'
        });
        breeze.NamingConvention.camelCase.setAsDefault();
        var mgr = new breeze.EntityManager('http://mysite.local/api/odata');
        return mgr;
    }

然后我尝试做一个简单的查询:

var query = breeze.EntityQuery.from('Countries').expand('Province').orderBy('name');

此查询成功,我得到一个包含几个国家/地区对象(加拿大和美国)的结果,但它缺少省份的导航属性。其他数据(id、名称、缩写)都按预期存在。我还尝试了与此相反的操作,并查询 Provinces 并扩展 Country 并得到相同的结果(无导航属性)。

我可以看到 Breeze 正确地附加了 $expand 并且请求 url 是我所期望的。

我了解到 OData 缺少 Breeze 所需的外键信息,但 Breeze 1.4.4 添加了对 OData v3 的支持,所以我不确定这是否应该工作?

谢谢。

编辑:这是生成的元数据以防万一:

<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
  <edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0">
    <Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="MyNamespace.Models">
      <EntityType Name="Country">
        <Key>
          <PropertyRef Name="Id"/>
        </Key>
        <Property Name="Name" Type="Edm.String" Nullable="false"/>
        <Property Name="Abbreviation" Type="Edm.String" Nullable="false"/>
        <Property Name="Id" Type="Edm.Int64" Nullable="false"/>
        <NavigationProperty Name="Provinces" Relationship="MyNamespace.Models.MyNamespace_Models_Country_Provinces_MyNamespace_Models_Province_ProvincesPartner" ToRole="Provinces" FromRole="ProvincesPartner"/>
      </EntityType>
      <EntityType Name="Province">
        <Key>
          <PropertyRef Name="Id"/>
        </Key>
        <Property Name="Name" Type="Edm.String" Nullable="false"/>
        <Property Name="Abbreviation" Type="Edm.String" Nullable="false"/>
        <Property Name="CountryId" Type="Edm.Int64" Nullable="false"/>
        <Property Name="Id" Type="Edm.Int64" Nullable="false"/>
        <NavigationProperty Name="Country" Relationship="MyNamespace.Models.MyNamespace_Models_Province_Country_MyNamespace_Models_Country_CountryPartner" ToRole="Country" FromRole="CountryPartner"/>
      </EntityType>
      <Association Name="MyNamespace_Models_Country_Provinces_MyNamespace_Models_Province_ProvincesPartner">
        <End Type="MyNamespace.Models.Province" Role="Provinces" Multiplicity="*"/>
        <End Type="MyNamespace.Models.Country" Role="ProvincesPartner" Multiplicity="0..1"/>
      </Association>
      <Association Name="MyNamespace_Models_Province_Country_MyNamespace_Models_Country_CountryPartner">
        <End Type="MyNamespace.Models.Country" Role="Country" Multiplicity="0..1"/>
        <End Type="MyNamespace.Models.Province" Role="CountryPartner" Multiplicity="0..1"/>
      </Association>
      <EntityContainer Name="Container" m:IsDefaultEntityContainer="true">
        <EntitySet Name="Countries" EntityType="MyNamespace.Models.Country"/>
        <EntitySet Name="Provinces" EntityType="MyNamespace.Models.Province"/>
        <AssociationSet Name="MyNamespace_Models_Country_Provinces_MyNamespace_Models_Province_ProvincesPartnerSet" Association="MyNamespace.Models.MyNamespace_Models_Country_Provinces_MyNamespace_Models_Province_ProvincesPartner">
          <End Role="ProvincesPartner" EntitySet="Countries"/>
          <End Role="Provinces" EntitySet="Provinces"/>
        </AssociationSet>
        <AssociationSet Name="MyNamespace_Models_Province_Country_MyNamespace_Models_Country_CountryPartnerSet" Association="MyNamespace.Models.MyNamespace_Models_Province_Country_MyNamespace_Models_Country_CountryPartner">
          <End Role="CountryPartner" EntitySet="Provinces"/>
          <End Role="Country" EntitySet="Countries"/>
        </AssociationSet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

【问题讨论】:

    标签: asp.net-web-api odata breeze


    【解决方案1】:

    这里的问题是 Microsoft 的 ODataConventionModelBuilder 目前没有为支持 EDMX 的模型公开 OData 约束。他们意识到了这一点,并声称他们计划在以后的版本中这样做。

    与此同时,您有几个选择。

    1) 忽略 ODataConventionBuilder 并使用默认的 Breeze WebApi2 实现直接与包装 EFModel 的 BreezeController 实例对话。这实际上支持 ODataConventionModelBuilder 将提供的超集,而没有任何额外的复杂性。请参阅 Breeze zip 中的任何 Breeze 示例。 (尤其是 DocCode 示例)。

    2) 使用 WCF DataService 将您的 EF 模型公开为 OData 服务。 WCF 数据服务确实公开了 OData 约束。

    我们计划在“不远”将来的某个时间提供有关您在这些领域中的每一个选项的附加文档。所以请继续关注。

    【讨论】:

    • 有没有人研究过扩展 ODataConventionBuilder 以支持这些约束?我真的希望坚持使用 web api 并使用 OData。
    • 我们已经讨论了一种允许您手动“调整”微风客户端数据模型以实现这一点的方法,但我们实际上并没有考虑修改 ODataConventionModelBuilder。但这是一种有趣的方法。我们希望 MS 在我们之前到达那里。
    猜你喜欢
    • 2014-05-17
    • 1970-01-01
    • 2013-08-24
    • 1970-01-01
    • 2014-05-24
    • 2017-05-25
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多