Metadata is used heavily by the Breeze.sharp client to determine the ‘shape’; of the entities that it will manage as well as the relationships between these entities. Data validation rules and mechanisms for translating server-side data onto the client may also be specified as metadata.
This metadata represents a combination of information gleaned from reflecting within your assemblies for .NET CLR information on types that implement the IEntity or IComplexObject interfaces in conjunction with data ( usually) returned from a server as a result of a call to the Breeze MetadataStore.FetchMetadata method. This call is made automatically by Breeze just before it attempts to perform it’s first query against a remote service (unless it is specifically directed not to). The metadata returned from the server as a result of this call may be in one of the following JSON formats.
Breeze metadata can also be described on the client via either of two methods:
In conjunction with the standard Breeze reflection of .NET assemblies containing implementations of IEntity and IComplexObject types).
As a result of this capability, Web services that are not under the developer’s control can be consumed and the data returned can be converted into fully capable breeze entities by performing the following two steps:
Note that even if both of these steps are skipped, any web service call will still return data to the breeze client. It’s just that in this case, the results returned will not be treated as entities.
Ideally, a Breeze.sharp application can get metadata from a server by calling the Breeze MetadataStore.FetchMetadata method.
Breeze fetches metadata automatically just before performing its first remote service query (unless you specifically told it not to). The metadata returned from the server may be in one of the following JSON formats.
When using the Breeze WebApi dataService adapter (the default), the format is either:
A Microsoft EDMX (CSDL) document serialized as JSON. Such a document is available for any Entity Framework DbContext or ObjectContext instance and is also available for a variety of other Microsoft products such as SharePoint.
A Breeze Metadata Format object as described below.
When using the Breeze OData dataService adapter, the format is an OData Metadata document per the OData specification. Remember to configure Breeze with the OData *dataService * adapter.
Many web services don’t provide metadata and include little-to-no type information in their JSON payloads. You can’t change this if it’s not your service.
You can always retrieve data from such services. Breeze won’t mind. But remember, Breeze can’t turn the incoming data into entities unless
Breeze won’t know what to do with data from a service that arrives looking like this:
[{Id: 1, Name: ‘blue’ }, {Id: 2, Name: ‘red’ }]
You may know that this is a list of two Color
entities. Breeze doesn’t.
You may be OK with this in which case you can tell Breeze to convert this data into an instance of an anonymous type, but…
The result will NOT be be entities. Breeze won’t cache them, track their changes, validate them, etc. Breeze is acting only as an HTTP retrieval mechanism and no more.
Alternatively, you can retrieve data as entities from such services with two-step client-side configuration:
For example, in Step #1 we define the Color
entity type in metadata. In Step #2, we tell Breeze how to recognize; {Id: 1, Name: 'blue'}
as an instance of the Color
entity type.
In this topic we’ll discuss step #1 - define metadata on the client. Step #2 - write the JsonResultsAdapter- is covered elsewhere.
There are two ways to define metadata on the client:
Breeze uses Metadata to describe the shape of the objects that it manages. These objects fall into two categories:
An entity’s metadata is described by an EntityType. This metadata includes:
Every entity in Breeze has an ‘entityType’ property that contains a reference to the EntityType that describes it.
The complex object’s metadata is described by a ComplexType. This metadata includes:
Note that a ComplexType does not define a key. This is the primary distinction between ComplexTypes and EntityTypes.
Every complex object in Breeze has a ‘complexType’ property that contains a reference to the ComplexType that describes it.
A Breeze NavigationProperty consists of the metadata for a property on the entity that will return instances of other entities. This metadata includes:
Breeze uses NavigationProperty metadata to automatically link related entities based on the foreign keys.
A Breeze DataProperty consists of the metadata for a property that will return either anything that is NOT an entity. Therefore a DataProperty is used to describe any property that returns any of the following.
Note: Because most SQL databases do not support the concept of a column containing a collection of data, DataProperties that return arrays are usually only found in applications working against NoSQL databases.
The metadata for a DataProperty includes:
Remember that MetadataStore.ExportMetadata can export metadata as a string in the Breeze Metadata Format. You can capture that format to file and, presto, you have metadata in an easily portable form.
Suppose
Put on your cleverness hat. Create that fake service with a fake Web API controller that does nothing more than return Metadata generated by the Breeze.NET EFContextProvider
** Not yet fully implemented in Breeze.Sharp - but coming soon. **
While the metadata that Breeze needs for its own internal processes are well defined, there is often the need for an application to have its own “custom” metadata as well. Often this metadata will be associated with an existing Metadata structure, such as an EntityType, ComplexType, DataProperty or NavigationProperty.
This is such a common requirement that Breeze supports the concept via the ability to attach “custom” properties to each of these structures. In particular:
The MetadataStore.ImportMetadata method supports “custom” nodes at the entity and property levels.
The MetadataStore.ExportMetadata method will automatically include any custom metadata within the store.
The MetadataStore.addEntityType method supports “custom” nodes on both the entity and property level.
For the EntityType, ComplexType, DataProperty and NavigationProperty classes:
var customMetadata = { "structuralTypes": [{ "shortName": "Customer", "namespace": "myNamespace", "dataProperties": [ { "nameOnServer": "CustomerID", "custom": { "description": "This customer's Id", "nestedDp": { "displayName": "Customer Id" } } }, { "name": "companyName", "custom": { "description": "The name of this company", "moreInfo": { hasServerValidation: true, "defaultLocale": "en-gb" } } } ], "navigationProperties": [ { "name": "orders", "custom": { "description": "The orders for this customer", navigation property", "nestedNp": { x: 3, y: 4 z: 7 } } } ], "custom": { "description": "A customer" "nestedXXX": { jsonInterceptorName: "foo", } } }] }; myEntityManager.metadataStore.importMetadata(customMetadata, true);