6

我正在使用 BreezeControllerAttribute 对带有 Web API 的 BreezeJS 进行试验。应如何公开实体上的计算属性?我发现可靠地做到这一点的唯一方法是创建一个从实体继承的中间 DTO 或使用投影。通常我会在这种情况下使用只读属性,但这些似乎被忽略了。

4

1 回答 1

14

当 Breeze 将 JSON 属性数据映射到实体时,它会忽略它无法识别的属性。这就是为什么您的服务器类的计算属性数据被丢弃,即使您在线上的 JSON 中看到它们。

幸运的是,您可以通过将其注册为未映射的属性来教 Breeze 识别该属性。我会告诉你怎么做。让我先介绍一些背景。

背景

如果您计算的属性是由数据库计算的属性,那么 Breeze 客户端将“知道”它。数据库支持的属性(常规的和计算的)在元数据中作为映射属性被拾取。

但是在您的情况下(如果我理解正确的话),该属性是在服务器端类的逻辑中定义的,而不是在数据库中。因此,它不在元数据中的映射属性中。它对元数据隐藏。它是一个未映射的实例属性。

我假设您没有将其隐藏在序列化程序中。如果您查看类查询的网络流量,您可以看到您计算的属性数据到达客户端。问题是 Breeze 在从这些查询结果中“具体化”实体时忽略了它。

示例解决方案

解决方案是在 MetadataStore 中注册计算的属性

我修改DocCode示例的 entityExtensionTests.js以包含此场景;您可以从 GitHub 获取该代码或等待下一个 Breeze 版本。

或者只是跟随下面的代码,从NorthwindModel.csEmployee类的这个片段开始:

// 未映射的,服务器端计算的属性
[NotMapped] // 从实体框架中隐藏;仍然序列化到客户端
公共字符串全名 {
    获取{返回姓氏+
             (String.IsNullOrWhiteSpace(FirstName)? "" : (", " + FirstName)); }
}

这是entityExtensionTests.js中的自动化测试

test("未映射的属性可以由服务器类的计算属性设置", 2,
  功能 () {

    var store = cloneModuleMetadataStore(); // 克隆 Northwind 元数据存储

    // 自定义员工构造函数
    varemployeeCtor = 函数 () {
        //'Fullname' 是 Employee 类的服务器端计算属性
        // 对于新实体,这个未映射的属性将为空
        // 但将在查询具体化期间为现有实体设置
        this.FullName = "";
    };

    // 注册自定义构造函数
    store.registerEntityTypeCtor("Employee", employeeCtor);

    var fullProp = store.getEntityType('Employee').getProperty('FullName');
    好的(fullProp && fullProp.isUnmapped,
        "'FullName' 应该是注册后未映射的属性");

    var em = newEm(store); // helper 使用这个 MetadataStore 创建一个管理器

    var query = EntityQuery.from('Employees').using(em);

    停止(); // 异步
    query.execute().then(success).fail(handleFail).fin(start);

    功能成功(数据){
        var first = data.results[0];
        var full = first.FullName();

        // 通过测试确认 FulllName 属性有值
        ok(full, "查询的'Employee'应该有一个全名('Last, First');它是"+full);
    }

});

您需要做的是在测试示例的这个小部分中:

var yourTypeCtor = 函数 () {
    this.calculatedProperty = ""; // "" 或任何类型的实例应该是
};

//注册你的自定义构造函数
store.registerEntityTypeCtor("YourType", yourTypeCtor);
于 2013-05-14T01:03:47.577 回答