The more I use BreezeJS the more I like it. I’m not using it with a .NET infrastructure so I’m hand rolling my metadata. Here’s a note of my findings for future reference.
key: The primary key for the entity. Can be a compound key. Required when new entities are created, loading by key and for reducing the amount of information required to describe navigation properties.
The science of relating entities together. We can have 1:1, 1:many and many:many (via a mapper collection) relationships. We can have parent to child relationships and inverse relationships (child to parent).
name: Arbitrary name of the property. In knockout land this will be the observable property that contains the related entity/entities
entityTypeName: The namespaced entity name of the related entity, eg Location:#Tinder
isScalar: Single(true) or many(false). For non scalar the related entities are embedded in an array, for scalar types the entity is embedded directly.
associationName: Arbitrary name of the relationship. Convention is <root entity>_<child entity>, eg Centre_Location. Must be unique, as it is used when describing relationships that have both forward and inverse relationships. In these cases the inverse relationship associationName must match the normal (forward?) relationship.
foreignKeyNames: Array of key names. These define the property on the root entity to use when fetching the related entity. This property value will relate to the primary key of the related entity. We do not need to specify the details of the related entity primary key here as this is defined in the related entity metadata.
Not sure how multiple keys would work but guess the ordering would match the compound key ordering in the related entity.
invForeignKeyNames: Array of key names. These define the relationship the other way around. These define the property on the related entity that matches the primary key of the root entity.
For most cases we only want to define normal or forward relationships where we state the parent to child relationship. For these cases the use of foreign and inverse keys depends if the relationship is 1:1 or many.
For 1:1 isScalar = true and the foreignKeyNames field is used.
For many isScalar = false and the invForeignKeyNames field is used.
I’ve not tried defining both foreignKeyNames and invForeignKeyNames for a relationship, upto now it’s only neccessary to define one. A possible exception might be for a many relationship. If the related entity does not map to the primary key of the root entity maybe it would be described with foreignKeyNames.
Using invForeignKeyNames can seem confusing, as it’s describing a forward relationship. It is useful though as the alternate would be to define an inverse relationship on the related entity back to the root which might be useful, but may result in extra response payload.