Q: How do I use inline mappings (the InlineMap) element?
Applies to: 2.0
It is common to group related elements in XML with another element. It is also common that this "wrapper" element does not directly correspond to any structure in the database. For example, consider the following:
<Customer> <Number>123</Number> <Name>Gallagher Industries</Name> <Address> <Street>123 Main St.</Street> <City>Chicago</City> <State>IL</State> <Country>US</Country> <PostCode>60609</PostCode> </Address> </Customer>
In this example, the Address element is used to group the address elements. However, it is unlikely to correspond to any structure in the database. That is, the address information is likely to be stored in the customer table, not in a separate address table.
The InlineMap element allows you to map the attributes, child elements, and PCDATA of a wrapper element as if they belonged to the parent of the wrapper element. For example, Street, City, State, Country, and PostCode can be mapped as if they were children of the Customer element, not the Address element. The main advantage of this is that it saves having to use XSLT to eliminate the Address element (on incoming documents) or add the Address element (on outgoing documents).
The InlineMap element type is similar to the ClassMap element type in that it has PropertyMap, InlineMap, and RelatedClass children. The PropertyMap children are used to map the attributes, child elements, and PCDATA of the wrapper element. The InlineMap children are used to map wrapper elements that are children of the wrapper element being wrapped. (Note that wrapper elements can be nested arbitrarily deep.) The RelatedClass children are used to map any children of the wrapper element that are mapped using ClassMaps.
For example, the ClassMap element used to map the Customer element type might be as follows. Notice that the PropertyMaps for Street, City, State, and so on are nested inside the InlineMap for Address. Notice also that the STREET column referred to in the PropertyMap for the Street element is in the CUSTOMERS table.
<ClassMap> <ElementType Name="Customer" /> <ToClassTable Name="CUSTOMERS" /> ... PropertyMap elements for Number and Name ... <InlineMap> <ElementType Name="Address" /> <PropertyMap> <ElementType Name="Street" /> <ToColumn Name="STREET" /> </PropertyMap> ... PropertyMap elements for City, State, Country, and PostCode ... </InlineMap> </ClassMap>
InlineMap elements can also have an optional OrderColumn or FixedOrder child. This is used to order the wrapper element among its siblings when constructing XML documents. For example, to ensure that the Number, Name, and Address children of Customer appear in that order, you can use the following FixedOrder elements:
<ClassMap> <ElementType Name="Customer" /> <ToClassTable Name="CUSTOMERS" /> <PropertyMap> <ElementType Name="Number" /> <ToColumn Name="NUMBER" /> <FixedOrder Value="1" /> <!-- FixedOrder --> </PropertyMap> <PropertyMap> <ElementType Name="Name" /> <ToColumn Name="NAME" /> <FixedOrder Value="2" /> <!-- FixedOrder --> </PropertyMap> <InlineMap> <ElementType Name="Address" /> <FixedOrder Value="3" /> <!-- FixedOrder --> ... PropertyMap elements for Street, City, State, Country, and PostCode ... </InlineMap> </ClassMap>
Note also that FixedOrder and OrderColumn elements in PropertyMap, InlineMap, and RelatedClass elements in an InlineMap refer to the order of the mapped element in the wrapper element, not the class element. For example, a FixedOrder element inside the PropertyMap for Street refers to the order of the Street element in Address, not Customer.
InlineMap elements have one restriction. Only a single child of a given type can be inlined. For example, in the following document, B can be inlined by D cannot. This is necessary for reconstructing the inlined element.
<A> <!-- B occurs once inside A and can be inlined. --> <B> <C>...</C> </B> <!-- D occurs more than once inside A and cannot be inlined. --> <D> <E>...</E> </D> <D> <E>...</E> </D> <F>...</F> </A>