This code should run as is in your browser.
<!DOCTYPE html>
<html>
<head>
<title>JayData testing</title>
<script type="text/javascript" src="jquery-1.9.1.js"></script>
<script type="text/javascript" src="jaydata.js"></script>
<script type="text/javascript" src="SqLiteProvider.js"></script>
<script type="text/javascript">
$data.Entity.extend('$data.Types.ReferencedEntity', {
Oid: {type: $data.Integer, key: true, computed: true},
Codigo: {type: $data.String},
Nombre: {type: $data.String},
MainsByOne: {type: $data.Array, elementType: '$data.Types.MainEntity', inverseProperty: 'ReferenceOne'},
MainsByTwo: {type: $data.Array, elementType: '$data.Types.MainEntity', inverseProperty: 'ReferenceTwo'}
});
$data.Entity.extend('$data.Types.MainEntity', {
Oid: {type: $data.Integer, key: true, computed: true},
Codigo: {type: $data.String},
ReferenceOne: {type: '$data.Types.ReferencedEntity', inverseProperty: 'MainsByOne'},
ReferenceTwo: {type: '$data.Types.ReferencedEntity', inverseProperty: 'MainsByTwo'}
});
$data.EntityContext.extend('$data.Types.LocalDBContext', {
ReferencedEntities: {type: $data.EntitySet, elementType: $data.Types.ReferencedEntity},
MainEntities: {type: $data.EntitySet, elementType: $data.Types.MainEntity}
});
window.app = {};
app.localdb = new $data.Types.LocalDBContext({
name: 'webSql',
databaseName: 'Test',
version: "1.0",
maxSize: 5 * 1024 * 1024,
dbCreation: $data.storageProviders.DbCreationType.DropTableIfChanged
});
app.localdb.onReady(function() {
console.log("smarterpjs.localdb.onReady!");
});
app.run = function() {
/* Create the entities */
var a = new $data.Types.ReferencedEntity();
app.localdb.ReferencedEntities.add(a);
a.Codigo = 'UNI';
a.Nombre = 'UNIDAD';
var m = new $data.Types.MainEntity();
app.localdb.MainEntities.add(m);
m.Codigo = 'MAIN';
m.ReferenceOne = a;
m.ReferenceTwo = a;
app.localdb.saveChanges();
/* Now query for editing... */
var query = app.localdb.MainEntities
.include('ReferenceOne')
.include('ReferenceTwo')
.filter(function(m) {
return m.Codigo === 'MAIN';
}, undefined)
.first();
query.then(function(result) {
/* As i need to 'edit' the result
* then i must attach the MainEntity itself,
* and the referenced objects ReferenceOne, and ReferenceTwo
*/
app.localdb.attach(result);
app.localdb.attach(result.ReferenceOne);
/* The problem comes here,
* as the entity Codigo 'MAIN' references on both fields 'ReferenceOne' and 'ReferenceTwo'
* the same 'ReferencedEntity'
*/
app.localdb.attach(result.ReferenceTwo);
});
}
</script>
</head>
<body>
<div onclick="app.run()">CLICK ME!</div>
</body>
</html>
Having that test app for jaydata, my question is embedded on the very same code. But i'try to explain more: i have a MainEntity table with 2 fields pointing to another ReferencedEntity table. For example:
ReferencedEntities = [ { Codigo: 'UNI' } ]
MainEntities = [ {
Codigo: 'MAIN',
ReferenceOne: { Codigo: 'UNI' } ,
ReferenceTwo: { Codigo: 'UNI' }
}
With this very simple data, when i try to load just one MainEntity for having it available completely, so the user can edit any of their fields, i get this error of:
**Context already contains this entity!!!**
Hope i get my point, and also the code runs showing the problem with current v1.3.2 of jaydata.
EDIT:
I've found "the way" to get a fully loaded object with its references, with an easy code.
The change is on the query.then(), as follows:
query.then(function(result) {
app.localdb.attach(result);
result.ReferenceOne = app.localdb.attachOrGet(result.ReferenceOne);
result.ReferenceTwo = app.localdb.attachOrGet(result.ReferenceTwo);
});
That way:
- I load every referenced entity always with attachOrGet, in case it is already on the context
- I assign each returned object to the original one, so the final "result" as everything in place for editing that instance, saving, and saving changes
Hope somebody find this useful!