カスタム JsonResultsAdapter で Breeze を使用してサードパーティ サービスに接続しようとしています。
サードパーティ サービスには、エンティティに関連する「メタデータ」が配列のルート ノードにあり、変数は「メタデータ」オブジェクトの「データ」プロパティにあります。
この形式には、関係を定義する 2 つの方法があります。1 つは、別のエンティティの ID を参照する「@ref」フィールドを介したものです。もう 1 つは、明示的な ID を持たず、「親」オブジェクトによってのみ参照される関連オブジェクトを (「@ref」の代わりに) インラインで定義することです。
データは次のようになります。
[{
"id" : "abc",
"type" : "foo",
"data": { "relationshipRef" : { "@ref" : "someid" } }
},
{
"id": "someid",
"type" : "bar",
"data" : { "relationshipInline" : { "type" : "baz",
"data" : { "something" : "whatever",
"innerRelation" : { "@ref" : "abc"}
}
}
}]
私は現在(JsonResultsAdapterのvisitNode関数で)「データ」オブジェクトのプロパティを「ルート」ノードに移動し、「@ref」プロパティを持つオブジェクトを「@ref」キーの値に置き換えています。最後に ID を追加します (関係が EntityType で元の名前を使用できるようにするため)。IE の場合、最初のオブジェクトは次のようになります。
{
"id" : "abc",
"type" : "foo",
"relationshipRefID" : "someid"
}
これは最上位のエンティティと関係に対しては機能しますが、ネストされたものには問題があります。
この問題をどのように解決しますか?
私は ComplexTypes を使用するつもりでしたが、上記のように必要な "navigationProperties" (関係) を持つことができないとドキュメントに記載されていました ("innerRelation" プロパティ)。
場合によっては、エンティティを 3 レベル程度までネストすることができます。
ここに私の現在の visitNode 関数があります:
visitNode: function(node, parseContext, nodeContext) {
if(node instanceof Object && node.type != null) {
if(node.deleted) {
//TODO: make sure the object is removed from the manager
return {ignore:true};
}
//We need to tweak the data structure to fit what breeze expects.
//It expects properties to be in the same level as the "metadata" for an object ("type" etc),
//So we need to move the properties from the data object into the node, and fix up relationships.
if(parseContext.entityManager.metadataStore.getEntityType(node.type, true) != null) {
var data = node.data;
for(var key in data) {
var prop = data[key];
//Move any foreign key fields to be "relationID":id instead of "relation":{"@ref":id}
if(prop instanceof Object) {
var ref = prop["@ref"];
if(ref != null) {
node[key+"ID"] = ref
data[key] = null;
continue;
}
}
//TODO: Handle inline references <- This is where I need help!
node[key] = data[key];
}
return {
entityType: node.type,
nodeId: node.id
}
}
else {
return {ignore:true};
}
}
}