JayData supports relationships since the first version, but it worths a short post to cover this feature.
If your application does more than saving and retrieving key-value pairs for configuration, you might arrive to a point when you want to manage relationships. JayData is able to manage relationships with navigations properties, so you don’t have to join the related tables by object identifiers. This feature – meaning the include() operation too – is available in the following data providers: OData, WebSQL/SQLite, WebSQL/SQLite Pro, MongoDB, MongoDB Pro.
Typed navigation properties can be defined easily by declaring the entity definitions.
1:N relationships
We will use the well-know Northwind example to understand the navigation properties.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="rem">//Define the Category entity with the Products array property</span> $data.Entity.extend(<span class="str">"Category"</span>, { Id: { key: <span class="kwrd">true</span>, type: <span class="str">"int"</span>, computed: <span class="kwrd">true</span> }, Name: { type: <span class="str">"string"</span>, required: <span class="kwrd">true</span> }, Products: { type: Array, elementType: <span class="str">"Product"</span>, inverseProperty: <span class="str">"Category"</span> } }); <span class="rem">//Define the Product entity with the Category reference</span> $data.Entity.extend(<span class="str">"Product"</span>, { Id: { key: <span class="kwrd">true</span>, type: <span class="str">"int"</span>, computed: <span class="kwrd">true</span> }, Name: { type: <span class="str">"string"</span>, required: <span class="kwrd">true</span> }, Category: { type: <span class="str">"Category"</span>, inverseProperty: <span class="str">"Products"</span> } }); <span class="rem">//Define our context to </span> $data.EntityContext.extend(<span class="str">"NorthwindContext"</span>, { Categories: { type: $data.EntitySet, elementType: Category }, Products: { type: $data.EntitySet, elementType: Product } }); <span class="rem">//Initialize a WebSQL/SQLite database connection with the defined schema</span> var nw = <span class="kwrd">new</span> NorthwindContext({ provider: <span class="str">"webSql"</span>, databaseName: <span class="str">"northwind"</span> }); |
Take notice of the inverseProperty in the declaration, which is necessary to be defined to help JayData to detect the other side of the relationship.
Once we instantiated our context, we can work with our database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<span class="rem">//Initialize a WebSQL/SQLite database connection with the defined schema</span> var nw = <span class="kwrd">new</span> NorthwindContext({ provider: <span class="str">"webSql"</span>, databaseName: <span class="str">"northwind"</span> }); nw.onReady(function () { <span class="rem">//create new category instance</span> var newDep = <span class="kwrd">new</span> Category({ Name: <span class="str">'Food'</span> }); <span class="rem">//add the new category to the context</span> nw.Categories.add(newDep); <span class="rem">//save the new category to the WebSQL database</span> nw.saveChanges(function () { <span class="rem">//query the persisted category from the database by the Name property</span> nw.Categories.first(<span class="str">"it.Name == 'Food'"</span>, {}, function (cat) { <span class="rem">//attach the existing category to the context to track changes and avoid persisting it again</span> nw.Categories.attach(cat); <span class="rem">//create a new product</span> var prod = <span class="kwrd">new</span> Product({ Name: <span class="str">'Bread'</span>, Category: cat <span class="rem">//set the existing category</span> }); <span class="rem">//add the new product to the context</span> nw.Products.add(prod); <span class="rem">//save the new product to the database</span> nw.Products.saveChanges(function () { <span class="rem">//read all the products from the DB with the related Category reference</span> <span class="rem">//without the include() oparator JayData doesn't load the navigation properties</span> nw.Products.include(<span class="str">'Category'</span>).toArray(function (p) { console.log(p); }); <span class="rem">//read all the categories with the related products </span> nw.Categories.include(<span class="str">'Products'</span>).toArray(function (c) { console.log(c); }); }); }); }) }); |
Try this code in a live example on JSFiddle!
In this snippet we access our database inside the onReady() of the context just to be sure that the context creation had finished. This example shows how to create a new product with an existing category by attaching the existing category to the context to track the changes of the objects and mark the state of category. Of course you can create a new category at a the same time, in this case you don’t have to use the attach() function.