我正在使用BreezeControllerAttribute和带有Web API的BreezeJS进行实验。实体的计算属性应如何公开?我发现可靠地做到这一点的唯一方法是创建一个从实体继承或使用投影的中间DTO。通常,在这种情况下,我将使用只读属性,但是这些属性似乎被忽略了。
最佳答案
当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
类的以下代码段开始:
//未映射的服务器端计算属性
[NotMapped]//隐藏在 Entity Framework 中;仍然序列化到客户端
公用字符串FullName {
得到{返回姓氏+
(String.IsNullOrWhiteSpace(FirstName)?“”:(“,” + FirstName))); }
}
这是entityExtensionTests.js中的自动测试
test(“未映射的属性可以通过服务器类的计算属性来设置,” 2,
功能 () {
var store = cloneModuleMetadataStore();//克隆Northwind MetadataStore
//自定义Employee构造函数
var employeeCtor = function(){
//'Fullname'是Employee类的服务器端计算属性
//对于新实体,此未映射的属性将为空
//,但将在查询实现期间为现有实体设置
this.FullName =“”;
};
//注册自定义构造函数
store.registerEntityTypeCtor(“Employee”,employeeCtor);
var fullProp = store.getEntityType('Employee')。getProperty('FullName');
ok(fullProp && fullProp.isUnmapped,
“'FullName'应该是注册后的未映射属性”);
var em = newEm(store);//助手使用此MetadataStore创建一个经理
var query = EntityQuery.from('Employees')。using(em);
停止();//异步
query.execute()。then(成功).fail(handleFail).fin(开始);
函数成功(数据){
var first = data.results [0];
var full = first.FullName();
//通过测试确认FulllName属性具有值
ok(完整,“查询的'雇员'应具有全名('姓氏,姓氏');它是“+完整”);
}
});
您需要做的是在测试示例的这一小部分中:
var yourTypeCtor = function(){
this.calculatedProperty =“”;//“”或任何类型的实例都应该是
};
//注册您的自定义构造函数
store.registerEntityTypeCtor(“YourType”,yourTypeCtor);
关于breeze - 使用breezejs和Web API处理计算的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16524073/