【问题标题】:OData returning children, but no Breeze property / method available on parent entityOData 返回子实体,但父实体上没有可用的 Breeze 属性/方法
【发布时间】:2014-05-09 14:26:45
【问题描述】:

我“成功”地对一个 asp.net web api ODATA 服务执行了一个微风查询,但似乎没有任何子级,即使响应中有子级。

查询: var 查询 = 微风.EntityQuery.from('交易') .take(20) .orderBy('Transaction_Timestamp desc') .expand('项目');

我如何访问孩子?我试过 .Items、.Items()、.Item、.Item(),那里没有属性或方法。在服务端,我验证了从 Transaction 到 Items (Transaction.Items) 和 Items.Transaction 的导航属性。而且,正如我所说,来自服务的 http 响应包含所有孩子的数据。

我在哪里可以查看问题可能出在哪里?

微风配置:

    breeze.config.initializeAdapterInstance('dataService', 'webApiOData', true);

    $http.defaults.headers.put = {
        'Access-Control-Allow-Origin': '*'
    };

    new breeze.ValidationOptions({ validateOnAttach: false }).setAsDefault();

    var metadataStore = createMetadataStore();
    etc.

我的交易类:

 public partial class Transaction
    {
        public Transaction()
        {
            this.Discounts = new HashSet<Discount>();
            this.Items = new HashSet<Item>();
            this.Tenders = new HashSet<Tender>();
        }

        public System.Guid Id { get; set; }
       ...

        public virtual ICollection<Item> Items { get; set; }

    }

我的物品类:

public partial class Item
{
    public System.Guid Id { get; set; }
    public System.Guid Transaction_Id { get; set; }

   ...

    public virtual Transaction Transaction { get; set; }
}

这还不够吗?

项目实体的odata/$metadata:

<EntityType Name="Item">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false"/>
<Property Name="Transaction_Id" Type="Edm.Guid" Nullable="false"/>
... (omitted fields)

<NavigationProperty Name="Transaction" Relationship="TransactionService.Models.TransactionService_Models_Item_Transaction_TransactionService_Models_Transaction_TransactionPartner" ToRole="Transaction" FromRole="TransactionPartner"/>
</EntityType>

这是 Transactions.Expand('Items') 微风查询中返回的数据:

{
  "odata.metadata":"http://localhost:49858/odata/$metadata#Transactions","value":[
    {
      "odata.type":"TransactionService.Models.Transaction","odata.id":"http://localhost:49858/odata/Transactions(guid'f93805cf-cc80-4d2e-9d9e-97df9c21c622')","Discounts@odata.navigationLinkUrl":"http://localhost:49858/odata/Transactions(guid'f93805cf-cc80-4d2e-9d9e-97df9c21c622')/Discounts","Shift@odata.navigationLinkUrl":"http://localhost:49858/odata/Transactions(guid'f93805cf-cc80-4d2e-9d9e-97df9c21c622')/Shift","Tenders@odata.navigationLinkUrl":"http://localhost:49858/odata/Transactions(guid'f93805cf-cc80-4d2e-9d9e-97df9c21c622')/Tenders","Items@odata.navigationLinkUrl":"http://localhost:49858/odata/Transactions(guid'f93805cf-cc80-4d2e-9d9e-97df9c21c622')/Items","Items":[
        {
          "odata.type":"TransactionService.Models.Item","odata.id":"http://localhost:49858/odata/Items(guid'511348d7-2886-4b13-ad7e-0eeb2a11bd85')","Transaction@odata.navigationLinkUrl":"http://localhost:49858/odata/Items(guid'511348d7-2886-4b13-ad7e-0eeb2a11bd85')/Transaction","Id@odata.type":"Edm.Guid","Id":"511348d7-2886-4b13-ad7e-0eeb2a11bd85","Transaction_Id@odata.type":"Edm.Guid","Transaction_Id":"f93805cf-cc80-4d2e-9d9e-97df9c21c622","Updated@odata.type":"Edm.DateTime","Updated":"2014-05-06T20:30:30.657","Ordinal@odata.type":"Edm.Int16","Ordinal":1,"Item_Type":"item      ","Item_Number":"39                  ","Parent_Ordinal":null,"Modifier@odata.type":"Edm.Byte","Modifier":0,"Description":"Cinnamon Coffee Cake","Item_Serial":null,...

等等……

【问题讨论】:

  • 你能展示你的模型和他们的关系吗?请记住,在您的模型定义中,您需要在两个模型之间建立适当的关系,以便 Breeze 知道当 Items 出现在 JSON 中时,它的类型为 Item 以正确映射它。
  • 我可能无法正确回答您的问题。所以你的意思是:你可以得到正确的响应,但你不能用 Breeze Api 读取扩展的项目?

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


【解决方案1】:

您能否向我们展示您的 Transaction 和 Items 模型类? 我敢打赌你在那里缺少一个外键......

请注意,仅在模型中设置导航属性不足以让 Breeze 检测到关联。

例子:

    //This will not work

    public class Transaction
    {
         public Transaction()
         {
            Items = new HashSet<Items>();
         }
         public int Id {get;set;}
         public virtual ICollection<Items> Items {get;set;}
    }

    public class Items
    {
       public int Id {get;set;}
       public Transaction Transaction {get;set;}
    }

一切看起来都不错,对吧?错了。

为什么?

因为 Items 类没有对父级的 FK 属性。您需要将类修改为如下所示:

   public class Items
   {
       public int Id {get;set;}
       public int TransactionId {get;set;} // FK Property

       public Transaction Transaction {get;set;}
   }

不是说这是你的问题,但你应该确认你已经正确设置了 FK 属性以便 Breeze 工作。

原因如下:http://www.breezejs.com/documentation/navigation-properties#foreignkeys

【讨论】:

  • 我在原始帖子中添加了更多信息,其中包含有关模型的详细信息以及从 odata 服务返回的内容。
  • Breeze 伙计们,我真的需要一些帮助!
【解决方案2】:

好的,调试的第一部分要求您在调用 EntityManager.fetchMetadata 后立即调查本地 EntityManager 中的元数据。 (此调用在第一次查询时自动发生,但也可以在第一次查询之前单独调用。)

我的猜测是,您从服务器获取的元数据在“项目”属性的定义方面并不完整。您可以在 EntityManager.fetchMetadata 调用之后通过深入了解您的“事务”EntityType 来检查这一点。像这样的:

 myEntityManager.fetchMetadata().then(function () {
     var transactionType = myEntityManager.metadataStore.getEntityType("Transaction");
     var itemsProperty = transactionType.getProperty("Items"); 
     // if itemsProperty is null; then it is likely that your server side model is not correct.
 });

请在您获得此测试结果后回复,我们或许可以确定更多信息。

【讨论】:

  • itemsProperty 为空。我想知道您是否可以从我上面已经发布的有关模型的信息以及有关从 ODATA 服务返回的元数据的信息中分辨出问题? BTW navigationProperties 和 foreignKeyProperties 都是 transactionType 对象上的空数组。
  • 不,你还没有给我足够的信息。 'itemsProperty' 为 null 的事实可能意味着您的 EF 模型未正确归因或您的 EF fluent 配置不正确。要确认这一点,只需尝试在服务器上针对 EF 执行查询,而不涉及任何微风。我的猜测是您的查询也会在那里失败。所以你需要先正确配置EF。
【解决方案3】:

一旦我更改了所有模型以删除所有下划线,事情就会变得更好。我建议在列名或表名中不要使用下划线。它们似乎不是外键名称的问题。

另外,我没有在服务端使用 Breeze EdmBuilder 模型构建器。

【讨论】:

    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    相关资源
    最近更新 更多