我遇到过一个问题,即如果两个子实体都与单个父实体相关,那么导航属性并不总是得到正确解析 - 它似乎取决于实体加载的顺序。
我在版本1.4.1中注意到了这一点。我以前在1.3.5,一切都很好。
代码示例可能更好地显示了这一点:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="../app/scripts/vendor/custom.modernizr.js"></script>
<script src="../app/scripts/vendor/jquery.js"></script>
<script src="./jquery.mockjax.js"></script>
<script src="../app/components/node-uuid/uuid.js"></script>
<!-- breeze and dependencies -->
<script src="../app/components/q/q.min.js"></script>
<script src="../app/components/breeze/Breeze.Client/Scripts/breeze.debug.js"></script>
<script>
var dataservice = new breeze.DataService({
serviceName: '/api', // the URL endpoint
hasServerMetadata: false // the service won't give us metadata
});
var DT = breeze.DataType; // alias
function defaultInitializer (entity) {
setId(entity);
}
function setId(entity) {
if (!(entity.id)) {
entity.id = uuid();
}
}
function Parent() { }
function Child() { }
function ProblemChild() { }
//#region private members
function initialize(metadataStore) {
var namespace = 'Namespace';
metadataStore.addEntityType({
shortName: 'Parent',
namespace: namespace,
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
name: { dataType: DT.String }
},
navigationProperties: {
children: {
entityTypeName: 'Child:#'+namespace,
isScalar: false,
associationName: 'Parent_Child'
},
problemChildren: {
entityTypeName: 'ProblemChild:#'+namespace,
isScalar: false,
associationName: 'Parent_Problem_Child'
}
}
});
metadataStore.addEntityType({
shortName: 'Child',
namespace: namespace,
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
parentId: { dataType: DT.Guid },
name: {dataType: DT.String}
},
navigationProperties: {
parent: {
entityTypeName: 'Parent:#'+namespace,
isScalar: true,
associationName: 'Parent_Child',
foreignKeyNames: ['parentId']
}
}
});
metadataStore.addEntityType({
shortName: 'ProblemChild',
namespace: namespace,
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
parentId: { dataType: DT.Guid },
name: {dataType: DT.String}
},
navigationProperties: {
parent: {
entityTypeName: 'Parent:#'+namespace,
isScalar: true,
associationName: 'Parent_Problem_Child',
foreignKeyNames: ['parentId']
}
}
});
metadataStore.registerEntityTypeCtor('Parent', Parent, defaultInitializer);
metadataStore.registerEntityTypeCtor('Child', Child, defaultInitializer);
metadataStore.registerEntityTypeCtor('ProblemChild', ProblemChild, defaultInitializer);
}
var model = {
initialize: initialize
};
var manager = new breeze.EntityManager({dataService: dataservice});
model.initialize(manager.metadataStore);
var parent = manager.createEntity('Parent', {name: 'Tony'});
var child = manager.createEntity('Child', {name: 'Tony Jr'});
var problemChild = manager.createEntity('ProblemChild', {name: 'Problem Tony Jr'});
child.parentId = parent.id;
problemChild.parentId = parent.id;
console.log('Created manually');
console.log(child.name, 'has a parent:', !!child.parent);
console.log(problemChild.name, 'has a parent:', !!problemChild.parent);
console.log(parent.name, 'has a child:', !!parent.children[0]);
console.log(parent.name, 'has a problem child:', !!parent.problemChildren[0]);
manager.clear();
var ctor = function () {
this.name = "mock";
this.defaultSettings = { };
};
ctor.prototype.initialize = function () {
};
ctor.prototype.ajax = function (settings) {
jQuery.ajax(settings);
};
breeze.config.registerAdapter("ajax", ctor);
breeze.config.initializeAdapterInstance("ajax", "mock", /*isDefault = */ true);
$.mockjax({
url: '/api/all',
responseTime: 0,
responseText: {
Entities: [
{
"id": "3",
"name": "Problem Jr (right)",
"parentId": "1",
$type: "ProblemChild:#Namespace"
},
{
"id": "1",
"name": "Tony (right)",
$type: "Parent:#Namespace"
},
{
"id": "2",
"name": "Tony Jr (right)",
"parentId": "1",
$type: "Child:#Namespace"
}
]
}
});
var resourceName = 'all';
var query = new breeze.EntityQuery().from(resourceName);
manager.executeQuery(query)
.then(function () {
parent = manager.getEntities('Parent')[0];
child = manager.getEntities('Child')[0];
problemChild = manager.getEntities('ProblemChild')[0];
console.log('\nLoaded in parent-child order');
console.log(child.name, 'has a parent:', !!child.parent);
console.log(problemChild.name, 'has a parent:', !!problemChild.parent);
console.log(parent.name, 'has a child:', !!parent.children[0]);
console.log(parent.name, 'has a problem child:', !!parent.problemChildren[0]);
})
.then(function () {
manager.clear();
$.mockjaxClear();
$.mockjax({
url: '/api/all',
responseTime: 0,
responseText: {
Entities: [
{
"id": "3",
"name": "Problem Jr (wrong)",
"parentId": "1",
$type: "ProblemChild:#Namespace"
},
{
"id": "2",
"name": "Tony Jr (wrong)",
"parentId": "1",
$type: "Child:#Namespace"
},
{
"id": "1",
"name": "Tony (wrong)",
$type: "Parent:#Namespace"
}
]
}
});
return manager.executeQuery(query);
})
.then(function () {
parent = manager.getEntities('Parent')[0];
child = manager.getEntities('Child')[0];
problemChild = manager.getEntities('ProblemChild')[0];
console.log('\nLoaded in child-parent order');
console.log(child.name, 'has a parent:', !!child.parent);
console.log(problemChild.name, 'has a parent:', !!problemChild.parent);
console.log(parent.name, 'has a child:', !!parent.children[0]);
console.log(parent.name, 'has a problem child:', !!parent.problemChildren[0]);
})
.fail(function () {
console.log('fail', arguments);
});
</script>
</head>
<body>
</body>
</html>
如果您加载此页面(您需要获取https://github.com/appendto/jquery-mockjax),那么您应该获得以下控制台输出:
Created manually breeze
Tony Jr has a parent: true breeze
Problem Tony Jr has a parent: true
Tony has a child: true
Tony has a problem child: true
MOCK GET: /api/all
Object {url: "/api/all", type: "GET", isLocal: false, global: true, processData: true…}
jquery.mockjax.js:530
Loaded in parent-child order
Tony Jr (right) has a parent: true
Problem Jr (right) has a parent: true
Tony (right) has a child: true
Tony (right) has a problem child: true
MOCK GET: /api/all
Object {url: "/api/all", type: "GET", isLocal: false, global: true, processData: true…}
jquery.mockjax.js:530
Loaded in child-parent order
Tony Jr (wrong) has a parent: false
Problem Jr (wrong) has a parent: true
Tony (wrong) has a child: false
Tony (wrong) has a problem child: true
最后一个例子证明了这个问题,其中改变加载数据的顺序意味着'Tony Jr'没有父母,而'Tony'没有孩子。 (两者都应该是假的。)
如何解决此问题?