【发布时间】:2014-12-24 16:47:59
【问题描述】:
大家好,我正在开发一个小型报表库 SPA,它使用 angular 和微风,允许用户管理他们创建的报表。我知道您可以通过引用 API 将微风与 EF 上下文一起使用来构建模型。但是这是如何实现的,我想将 EF 排除在外。 API (WebAPI 2) 基本上是调用其他存储库来完成工作,几乎就像一个接口。返回的结果只是一个 json 对象。我查看了 Breeze 网站上的 Edmunds 示例,我可以看到如何构建客户端模型以及处理返回的映射。我当前遇到的问题是我不确定 jsonResultsAdapter 中的映射是否正确。或者我可能遗漏了一些关于映射应该如何工作的东西。
我目前正在使用一些已存入 API 的模拟数据对此进行测试,直到我可以让它工作为止。一旦绑定和映射,我就可以反对实际数据。这是我到目前为止所拥有的: 模拟数据是一个报表对象,其中包含一个称为标签(基本上是标签)的内部集合,一个报表可以有多个标签,并且从标签中它可以有多个报表。
//report dto
public class ReportDto
{
public Int64 ReportId { get; set; }
public string ReportName { get; set; }
public string ReportDescription { get; set; }
public string ReportDateCreated { get; set; }
public string ReportOwner { get; set; }
public IEnumerable<ReportLabelDto> ReportLabels { get; set; }
}
public class ReportLabelDto
{
public Int64 LabelId { get; set; }
public string LabelName { get; set; }
public bool IsPrivate { get; set; }
public bool IsFavorite { get; set; }
public IEnumerable<ReportDto> Reports { get; set; }//placeholder?
}
这是当前在 webapi 控制器中使用的代码,此时仅用于测试:
[Route ("reportlibrary/myreports/{userid}")]
public IEnumerable<ReportDto> GetAllReports(string userId)
{
List<ReportDto> result = new List<ReportDto>();
List<ReportLabelDto> label = new List<ReportLabelDto>();
//create 5 reports
for (int i = 0; i < 5; i++)
{
ReportDto r = new ReportDto();
ReportLabelDto l = new ReportLabelDto();
r.ReportId = i;
r.ReportOwner = "John Smith";
r.ReportDateCreated = DateTime.Now.ToString();
r.ReportDescription = "Report Description # " + i.ToString();
r.ReportName = "Report Description # " + i.ToString();
//generate labels
l.LabelId = i;
l.LabelName = "Special Label" + i.ToString();
l.IsPrivate = true;
l.IsFavorite = false;
label.Add(l);
r.ReportLabels = label;
result.Add(r);
}
return result;
}
当前返回的对象如下所示:
[{"ReportId":0,"ReportName":"Report Description # 0","ReportDescription":"Report Description # 0","ReportDateCreated":"12/22/2014 6:32:05 PM","ReportOwner":"John Smith","ReportLabels":[{"LabelId":0,"LabelName":"Special Label0","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":1,"LabelName":"Special Label1","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":2,"LabelName":"Special Label2","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":3,"LabelName":"Special Label3","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":4,"LabelName":"Special Label4","IsPrivate":true,"IsFavorite":false,"Reports":null}]},{"ReportId":1,"ReportName":"Report Description # 1","ReportDescription":"Report Description # 1","ReportDateCreated":"12/22/2014 6:32:05 PM","ReportOwner":"John Smith","ReportLabels":[{"LabelId":0,"LabelName":"Special Label0","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":1,"LabelName":"Special Label1","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":2,"LabelName":"Special Label2","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":3,"LabelName":"Special Label3","IsPrivate":true,"IsFavorite":false,"Reports":null},{"LabelId":4,"LabelName":"Special Label4","IsPrivate":true,"IsFavorite":false,"Reports":null}]},...]
我的服务和控制器都在说话,我可以点击 api 并返回一个对象,所以我现在将省略该代码。
对于js模型我定义了report对象如下:
app.factory('model', function () {
var DT = breeze.DataType;
return {
initialize: initialize
}
function initialize(metadataStore) {
metadataStore.addEntityType({
shortName: "Report",
namespace: "Inform",
dataProperties: {
reportid: { dataType: DT.Int64, isPartOfKey: true },
reportname: { dataType: DT.String },
reportdescription: { dataType: DT.String },
reportdatecreated: { dataType: DT.String },
reportowner: { dataType: DT.String },
mappedlabels: { dataType: DT.Undefined },
ishared: { dataType: DT.Bool },
isfavorite: { dataType: DT.Bool }
},
navigationProperties: {
labels: {
entityTypeName: "Label:#Inform", isScalar: false,
associationName: "Report_Labels"
}
}
});
metadataStore.addEntityType({
shortName: "Label",
namespace: "Inform",
dataProperties: {
labelid: { dataType: DT.Int64, isPartOfKey: true },
reportid: { dataType: DT.Int64 },
labelname: { dataType: DT.String },
ispublic: { dataType: DT.Bool },
mappedreports: { dataType: DT.Undefined }
},
navigationProperties: {
labels: {
entityTypeName: "Report:#Inform", isScalar: false,
associationName: "Report_Labels", foreignKeyNames: ["reportid"]
}
}
});
}
})
我认为问题在于我对这个适配器的了解不够,无法确保我收到我认为的内容以及它是否正确处理映射:
/* jsonResultsAdapter: parses report data into entities */
app.value('jsonResultsAdapter',
new breeze.JsonResultsAdapter({
name: "inform",
extractResults: function (data) {
var results = data.results;
if (!results) throw new Error("Unable to resolve 'results' property");
// Parse only the make and model types
return results && (results.reportHolder || results.labelHolder);
},
visitNode: function (node, parseContext, nodeContext) {
//Report parser
if (node.reportid && node.labels) {
node.mappedlabels = node.labels;
node.labels = [];
return { entityType: "Report" }
}
// Label parser
else if (node.labelid && node.reports) {
node.mappedreports = node.reports;
node.mappedreports = [];
return { entityType: "Label" };
}
}
}));
当我单步执行 chrome 中的代码时,我可以看到返回了一个对象。有 5 个报告,每个报告有 5 个标签(我知道标签目前显示空报告)。当我在 jsonResultsAdapter 中设置断点时,我可以看到包含 5 个对象的结果,但是传递回服务的结果是 null。谁能帮我验证模型和映射是否正确,或者您是否在 jsonResultsAdapter 中看到任何不合适的地方。对于我可能想做的不同事情的任何建议,我也很感激。我现在感觉很黑箱,因为我没有看到/理解解决此映射块的好方法。
-干杯
【问题讨论】: