【问题标题】:Handling calculated properties with breezejs and web api使用breathjs和web api处理计算的属性
【发布时间】:2013-08-02 15:26:45
【问题描述】:

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

【问题讨论】:

    标签: breeze asp.net-web-api


    【解决方案1】:

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

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

    背景

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

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

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

    示例解决方案

    解决办法是register the calculated property in the MetadataStore

    我修改了the entityExtensionTests.js of the DocCode sample 以包含这个场景;您可以从 GitHub 获取该代码或等待下一个 Breeze 版本。

    或者只是跟随下面的代码,从 NorthwindModel.cs 中的 Employee 类中的这个 sn-p 开始

    // 未映射的,服务器端计算的属性 [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);

    【讨论】:

    • 我完全按照你的描述做了,但是计算的属性没有从查询结果中得到它的值,即使数据传输到客户端它也总是空的。有什么隐藏的魔法吗?您描述为评论的行为没有发生“//但将在查询实现期间为现有实体设置”!
    • 我刚刚发现问题在于数据和定义的客户端属性之间的大小写不匹配。此示例按预期工作。
    • @Ward 使用 camelCase 命名约定时出现问题。它尝试映射 yourType.CalcProperty 而不是 yourType.calcProperty。其他所有内容都是驼峰式,但服务器发送了 Pascal Case,这似乎忽略了它:(
    • 为什么你认为camelCase约定有问题。它完全按照它所说的去做:将 PascalCase 服务器端属性名称转换为客户端 camelCase 属性名称。当然它会“误解”一个 camelCase server 属性名;那些在其域中不存在。如果它们存在于 您的 域中,请为自己编写一个满足您需求的自定义 NamingConvention。这是一个非常简单的 API,编写自定义 NamingConvention 正是我们希望/期望您在您所描述的情况下做的事情。
    猜你喜欢
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 2017-03-27
    • 2023-03-28
    • 1970-01-01
    • 2021-05-09
    • 2014-12-26
    • 1970-01-01
    相关资源
    最近更新 更多