为什么我的breeze实体没有加入子对象列表?

时间:2014-03-04 16:50:54

标签: angularjs breeze hottowel

这次我有一个轻而易举的问题:)

为什么微风不会加入相关对象。从服务器上的存储库方法返回适当的数据。您可以从我的提琴手数据中看到客户端正在接收数据。

我的理解是,如果从服务器返回数据,则不必在客户端查询上手动调用“extend”方法。

对象关系是

1)一个物品可以有很多单位 2)单位可以涉及许多项目

从Breezejs.com文档复制

省略导航属性 有时您想要省略关联一侧的导航属性。例如,你可能有Person.Gender但你不想要Gender.Persons;没有充分的理由从“男性”性别实体导航到所有男性人员,没有理由承担为该导航更新可观察数组的开销。幸运的是,您可以在关联的原则方面省略导航属性。性别是此示例中的主体,因此您可以省略Gender.Persons。

- 数据库表结构

   CREATE TABLE [dbo].[Item](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Name] [varchar](50) NOT NULL,
 [DisplayOrder] [int] NOT NULL
    )

   CREATE TABLE [dbo].[Unit](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Acronym] [varchar](10) NULL,
 [Name] [varchar](50) NULL,
 [DisplayOrder] [int] NULL
     )

    CREATE TABLE [dbo].[AvailableUnit](
  [ItemId] [int] NOT NULL,
  [UnitId] [int] NOT NULL,
    CONSTRAINT [PK_AvailableUnit] PRIMARY KEY CLUSTERED 
    ([ItemId] ASC,[UnitId] ASC
     )

- EF 6地图

  public class ItemMap : EntityTypeConfiguration<Item> {

    public ItemMap ( ) {
        ToTable( "Item" );
        HasKey( k => new {  k.Id } );

        Property( p => p.Id ).HasColumnName( "Id" );
        Property( p => p.Name ).HasColumnName( "Name" ).HasMaxLength( 50 );
        Property( p => p.DisplayOrder ).HasColumnName( "DisplayOrder" );

        HasMany( t => t.Units )
            .WithMany( )
            .Map( m => {
                      m.ToTable( "AvailableUnit" );
                      m.MapLeftKey( "ItemId" );
                      m.MapRightKey( "UnitId" );
                  } );
     }

  }

public class UnitMap : EntityTypeConfiguration<Unit> {
    public UnitMap( ) {
        ToTable( "Unit" );
        HasKey( k => new { k.Id } );
        Property( p => p.Id ).HasColumnName( "Id" );
        Property( p => p.Acronym ).HasColumnName( "Acronym"   ).HasMaxLength(10).IsRequired();
        Property( p => p.Name ).HasColumnName( "Name" ).HasMaxLength( 50 );
        Property( p => p.DisplayOrder ).HasColumnName( "DisplayOrder" );
    }
} 

- 样本类

 public class Item {

    public int Id { get; set; }
    public string Name { get; set; }
    public int? DisplayOrder { get; set; }

    public virtual List<Unit> Units { get; set; }

    public Item( ) { }
}

public class Unit {

    public int Id { get; set; }
    public string Acronym { get; set; }
    public string Name { get; set; }
    public int? DisplayOrder { get; set; }

    public Unit() { }
}

---存储库方法

    public IQueryable<Items> Items {
        get {
            return Context.Items
                .Include( i => i.Units );
        }
    }

----来自FIDDLER的JSON

 [
  {
    "$id": "1",
    "$type": "MyProject.Core.Item, MyProject.Core",
    "Id": 1,
    "Name": "Alprostadil",
    "Units": [
    {
       "$id": "8",
       "$type": "MyProject.Core.Unit, MyProject.Core",
       "Id": 1,
       "Acronym": "U1",
       "Name": "Unit 1",
       "DisplayOrder": 10
    },
    {
       "$id": "9",
       "$type": "MyProject.Core.Unit, MyProject.Core",
       "Id": 2,
       "Acronym": "U2",
       "Name": "Unit 2",
       "DisplayOrder": 20
  },
  {
       "$id": "10",
       "$type": "MyProject.Core.Unit, MyProject.Core",
       "Id": 3,
       "Acronym": "U3",
       "Name": "Unit 3",
       "DisplayOrder": 30
  },
  {
        "$id": "11",
        "$type": "MyProject.Core.Unit, MyProject.Core",
        "Id": 4,
        "Acronym": "U4",
        "Name": "Unit 4",
        "DisplayOrder": 40
  }
],    
  "DisplayOrder": 10
 }
]

- 抽象存储库中的热毛巾方法

       function _getById(entityName, id, forceRemote) {
           var self = this;
           var manager = self.manager;
           if (!forceRemote) {
            // check cache first
            var entity = manager.getEntityByKey(entityName, id);
            if (entity && !entity.isPartial) {
                self.log('Retrieved [' + entityName + '] id:' + entity.id + ' from  cache.', entity, true);
                if (entity.entityAspect.entityState.isDeleted()) {
                    entity = null; // hide session marked-for-delete
                }
                return $q.when(entity);
            }
        }

        // Hit the server
        // It was not found in cache, so let's query for it.
        return manager.fetchEntityByKey(entityName, id)
            .to$q(querySucceeded, self._queryFailed);

        function querySucceeded(data) {
            entity = data.entity;
            if (!entity) {
                self.log('Could not find [' + entityName + '] id:' + id, null, true);
                return null;
            }
            entity.isPartial = false;
            self.log('Retrieved [' + entityName + '] id ' + entity.id
                + ' from remote data source', entity, true);
            self.zStorage.save();
            return entity;
        }
    }

3 个答案:

答案 0 :(得分:0)

您的单元类似乎缺少将其链接到项目的导航属性。将以下属性添加到Unit类 -

public class Unit {

    public int Id { get; set; }
    public string Name { get; set; }
    public string Acronym { get; set; }
    public int ItemId { get; set; }
    public int? DisplayOrder { get; set; }

    public virtual Item Item { get; set; }

    public Unit( ) { }
}

这让我们的Breeze知道你的单位何时具体化了他们所属的物品。

修改

对不起,我错过了你说单位是一个复杂类型的问题的标题。复杂类型没有Id作为键 - 我相信您需要从单元中删除ID以使EF将其定义为复杂类型,或者至少使用非常规方式提供Id

public class Unit {

    public string Name { get; set; }
    public string Acronym { get; set; }
    public int? DisplayOrder { get; set; }

    public Unit( ) { }
}

答案 1 :(得分:0)

GregL, 一对多的一面是Breeze文档描述的主要方面。因此,如果您将数据模型与Breeze文档使用的示例进行比较,则Item&lt; ==&gt;人,单位&lt; ==&gt;性别。所以你想省略关系的另一面,我不认为Breeze可以处理,因为它需要一个外键属性或“很多”侧类型的导航属性来知道如何将它与“一个”相关联“侧面型。只有一个单元集合,它不知道这些对象上用什么属性来形成与Item的关系。

答案 2 :(得分:0)

轮到我了: - )

  • ItemUnit是两个普通的实体类,映射到不同的数据库表。

  • 因此Unit不是一个复杂的类型,这不是问题。

  • 您忽略了调出“AvailableUnit”表,该表实现了ItemUnit之间的关系多对多关联。

    HasMany( t => t.Units )
        .WithMany( )
        .Map( m => {
                  m.ToTable( "AvailableUnit" );
                  m.MapLeftKey( "ItemId" );
                  m.MapRightKey( "UnitId" );
              } );
    
  • Breeze does not support many-to-many associations。功能请求在user voice中有很多投票。添加你的投票。

  • 您可以(正如您所发现的那样)将相关的Units从服务器发送到有效负载中的客户端。嵌套的Units在缓存中......你可以在那里找到它们。但是Breeze不会为您填充Item.Units数组,也不会为您维护它。这些任务落在你身上。

  • 我们一直建议采用不同的方法。我们要求您将映射/链接公开为独立实体,例如AvailableUnit。然后你就可以走Item.AvailableUnit.Unit路径了。

  • 您必须自己管理链接实体(AvailableUnit)。 Breeze文档描述了一种显示方式和manage many-to-many scenarios以这种方式定义的方式。

我怀疑这不是你想要听到的答案。就是这样。