0

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!

Javier Castro
  • 321
  • 3
  • 12

1 Answers1

0

I do not think that it will work. You can try to use attachOrGet when you attach the second child..

Gabor Dolla
  • 2,680
  • 4
  • 14
  • 13
  • That way, first i already must know that the second line "will" throw an error cause ReferenceOne and ReferenceTwo are equal, and then, use attachOrGet which will give me a new object, and set it to the previous one with result.ReferenceTwo = ... attachOrGet(result.ReferenceTwo) . Is that what you mean? – Javier Castro Oct 31 '13 at 20:26
  • attachOrGet gives you the object that is in the context already or attaches the parameter. – Gabor Dolla Nov 04 '13 at 12:25