BreezeJS选择系列

时间:2013-05-21 16:33:15

标签: breeze

这与以下问题有关: BreezeJS Selecting ComplexType properties

所以:

public class Person {
   public int Id {get;set;}
   public string Name {get;set;}
   public Address MyAddress {get;set;}
   public virtual ICollection<Pet> Pets {get;set;}
}

我想致电

EntityQuery.from('Person').select('id,name,pets').orderBy('id');

并映射到 personBrief 对象。

我知道有一个:

.toType("personBrief") 

扩展,但它似乎“找不到具有该描述的对象”(我在哪里可以定义它?),并且在线帮助说没有支持复杂类型。

然后我尝试了Jumpstart HotTowel tutorial

中的 mapDtosToEntities()函数

此方法似乎只能成功映射非数组属性。从Breeze查询返回的Dto正确填充了 pets 集合。我尝试将它们循环推送到 ko.observableArray 但是事件虽然它填充了我的新实体,但是breeze失败并且“可能没有设置集合导航属性”错误。

最后,我想在初始化程序中创建一个Computed。

personBrief.sumOfPetAges = ko.computed(function() {
            var sum = 0;

            person.pets().forEach(function (i) {
                sum += i.petAge();
            });
            return sum;
        });

任何想法如何在投影后保留对象图?感谢

1 个答案:

答案 0 :(得分:0)

您是否将PersonBrief定义为EntityType?我打赌不是......特别是考虑到你在你的样本中称它为“personBrief”。 toType()方法用于投射简单,平坦,已知的EntityType。所以我觉得你在这里偏离轨道了。

为什么不转发给Person?当然缺少一些Person材料(如在CCJS中......虽然不是在您投影所有数据属性的特定示例中)。但它非常简单。只需写下toType('Person')即可。你试过吗?

如果您确实想要在客户端上定义此类EntityType,则可以as described in the docs。如果这样做,您可以使用toType()强制转换为该类型,Breeze将在缓存中跟踪它。当然,将这样的东西保存回服务器是另一回事。这是可行的...它可能是一种DTO ......但你必须在服务器上编写拦截逻辑并将数据转换为真实的服务器端持久实体,这条路径超出了我的答案范围

这是一些代码......写在我的头顶......但它应该指向正确的方向。请注意,我假设Pet是EntityType,而不是ComplexType!此时Breeze不支持ComplexTypes的数组(它会在今天不支持)。

   // Define a PersonBrief type for a given MetadataStore
   function addPersonBriefType(metadataStore) {
        var perType = metadataStore.getEntityType('Person');

        var type = new breeze.EntityType({
            shortName: 'PersonBrief',
            namespace: perType.namespace 
        });
        var idProperty = new breeze.DataProperty({
            nameOnServer: 'Id',
            dataType: breeze.DataType.Int32,
            isPartOfKey: true,
        });
        type.addProperty(idProperty);
        type.addProperty(new breeze.DataProperty({ nameOnServer: 'Name' }));

        // Here's how you define your Pets collection
        // I assume that you already have a Pet type in metadata and
        // it has an inverse navigation back to Person
        // Get the navigation property from Person to Pets
        var assoc = perType.getNavigationProperty('Pets');

        type.addProperty(new breeze.NavigationProperty({
            nameOnServer: 'Pets',
            isScalar: false, // it's a collection
            entityTypeName: assoc.entityType.name,
            foreignKeyNames: assoc.inverse.foreignKeyNames,
            associationName: assoc.associationName
        }));

        metadataStore.addEntityType(type);
        return type;
    }

我能够在DocCode示例的 metadataTests.js 中使用EmployeePartial执行此类操作,其中Pets的等效项为Orders。可比较的投影查询是这样的:

var query = breeze.EntityQuery.from('Employees')
    .where('EmployeeID', 'eq', 1)
    .select('EmployeeID, FirstName, LastName, Orders')
    .toType('EmployeePartial')

您的sumOfPetAges计算应该有效,因为有PersonBrief类型需要补充。

我自己也是为了确定。即使我不能发誓我在这里编写的这段特殊代码,我知道它仍然有效。让我们知道这是怎么回事。

P.S。虽然您应该可以从PersonBrief导航到Pets,但不要期望从Pet导航回PersonBrief;导航属性未定义。