EDM model plays a very important role in OData. When you want to use OData, the first thing should be constructing an EDM model. Previously, you need to build a complete EDM model, which means all types, terms, operations used in an EDM model should be declared in itself. If there are some elements in an existing model (CSDL), which you want to use when constructing a new model. The only method is “re-declared” them in the new model before using. It is costly and unworthy. Now, ODL provides a feature called “Model Reference”. If the new model (referencing model) want to use some types in an existing model (referenced model), you need to add a “Reference” of existing model in new model. Then, you can directly using the type defined in existing model without re-declaring it in the new model. With model reference, you can divide a model into many small pieces and reference them in a main model, which is more flexible than before. In this article, we will briefly introduce how to use model reference in OData.
There are two methods to get an EDM model. Constructing model in memory by APIs provided on IEdmModel or parsing the existing CSDL by API “EdmxReader.TryParse”. We use the sample example to demo how to consume “Model Reference” in both methods.
Suppose you have a model called “ReferencedModel” as following:
You want to construct a new model (MainModel), which will use some elements in ReferencedModel. The main model is as the following:
In MainModel, entity type “Customer” is extended from “Person”, which is declared in ReferencedModel. The type of property “HomeAddress” in Customer is “Address”, which is from ReferencedModel, too.
The referenced model may be saved in a FTP server, or shared from a web site. No matter where it is, you need to parse it to IEdmModel before using it. The following code is used to parse “ReferencedModel” to IEdmModel, which is saved in local disk:
After getting the IEdmModel, you need to find all elements which will be used in the new model. In the example, “Person” and “Address” type can be found as following:
Besides the type, term and operation can also be found via different APIs:
In the new model, the elements found in referenced model can be directly used to construct the new model. In our example, the following code is used to construct “MainModel”:
As there are some types from “ReferencedModel” used in “MainModel”. The reference information needs to be added in “MainModel”, including the attribute Namespace and Uri. Please make sure that the Uri should be an accessible address to get the “ReferencedModel”. Since client side needs to know the referenced model when parsing the “MainModel”. The following code is to add the reference in “MainModel”.
If you do not want to build the model through API on EdmModel, you can also write a CSDL to represent the model, then parse it to IEdmModel. In our example, the following code are used to parse “MainModel” (please refer the CSDL above). The getReferencedSchemaFunc method needs to be provided as a parameter for parsing, to return the XmlReader for referenced model.
There is no much difference between writing a normal EDM model and an EDM model contains referenced model. For instance, the following code is to write the “MainModel”:
Previously, method “ReadMetadataDocument()” is used to read the service metadata and parse it to IEdmModel. But for the model which contains referenced model, “ReadMetadataDocument()” is not enough. Referenced models also need to be parsed during the parsing. Thus, “getReferencedSchemaFunc()” need to be passed to “ReadMetadataDocument(Func<Uri, System.Xml.XmlReader> getReferencedModelReaderFunc)” as the parameter, which is used to get referenced model by “Uri” of reference. The code are as following:
You may need to search the element in IEdmModel. “FindDeclaredXXX” APIs defined in IEdmModel are used to find the elements declared in model, but they do not support search in referenced model. The following APIs are used to do cross-model search:
The same as before, only metadata Uri is needed for CodeGen to generate client code for the metadata containing reference element. CodeGen will get the reference model automatically. But, the Uri of reference element should be an http/https path or file path.