October 11, 2009
After introducing the XML format of Entity Framework’s edmx files, let’s use that knowledge to create a small XSLT style sheet which displays the mappings of tables and entities in a Wiki-style table (which can be used in MediaWiki and SharePoint wikis).
In the XSLT root, we need to declare all namespaces used by the edmx to access nodes and attributes:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/
EntityStoreSchemaGenerator"
xmlns:ssdl="http://schemas.microsoft.com/ado/2006/04/edm/ssdl"
xmlns:cs="urn:schemas-microsoft-com:windows:storage:mapping:CS"
xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm"
xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration"
xml:space="default" >
<xsl:output method="html" omit-xml-declaration="yes" />
<!-- input file is C:\path\to\Model.edmx -->
This XSLT does not start with the mappings section, but with the tables and views inside the Schema definition, and then looks up their Mappings definition:
<xsl:template match="/">
<xsl:apply-templates
select="edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema" />
</xsl:template>
<xsl:template match="ssdl:Schema">
<html>
<body>
<table width="100%">
<xsl:apply-templates select="ssdl:EntityType" >
<xsl:with-param name="namespace" select="@Namespace" />
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
This code creates a table row for each database table and its class:
<xsl:template match="ssdl:EntityType" >
<xsl:param name="namespace"></xsl:param>
<xsl:variable name="table" select="@Name" ></xsl:variable>
<xsl:variable name="map"
select="/edmx:Edmx/edmx:Runtime/edmx:Mappings/cs:Mapping/
cs:EntityContainerMapping/
cs:EntitySetMapping[cs:EntityTypeMapping/
cs:MappingFragment/@StoreEntitySet=$table]" />
<xsl:variable name="s" select="$map/*/@TypeName" />
<xsl:variable name="p"
select="concat('IsTypeOf(',
substring($namespace, 1, string-length($namespace) - 5))" />
<xsl:variable name="class"
select="substring($s, string-length($p) + 1,
string-length($s) - string-length($p) - 1)">
</xsl:variable>
<tr valign="top">
<td >
[[<xsl:value-of select="@Name"/>]]
</td>
<td>
<xsl:value-of select="$class" />
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
The [[ ]] notation creates a wiki hyperlink that allows developers to document tables and entities, and link to other documentation.
Leave a Comment » |
Documentation Generation, Entity Framework, Mediawiki |
Permalink
Posted by devio
October 5, 2009
The Entity Designer of Visual Studio 2008 stores its data in an XML file with the extension .edmx. In the first part of this series I covered the Storage Model, the second part dealt with the Conceptual Model.
This part covers the Mappings section with regard to C# mappings. The Mapping section uses the xmlns:cs namespace
- xmlns:cs=”urn:schemas-microsoft-com:windows:storage:mapping:CS”
For tables and views, the mapping section defines the mappings from database object to C# class (EntitySets and EntityTypes), along with their scalar properties:
<edmx:Mappings>
<cs:Mapping Space="C-S" >
<cs:EntityContainerMapping
StorageEntityContainer="MyNamespaceEntitiesStoreContainer"
CdmEntityContainer="MyEntities">
<cs:EntitySetMapping Name="TableFooSet">
<cs:EntityTypeMapping TypeName="IsTypeOf(My.Namespace.Entities.TableFoo)">
<cs:MappingFragment StoreEntitySet="TABLEFOO">
<cs:ScalarProperty Name="ID" ColumnName="ID" />
<cs:ScalarProperty Name="Name" ColumnName="NAME" />
</cs:MappingFragment>
</cs:EntityTypeMapping>
</cs:EntitySetMapping>
<cs:AssociationSetMapping Name="FK_TABLEFOO_TABLEBAR"
TypeName="My.Namespace.Entities.FK_TABLEFOO_TABLEBAR"
StoreEntitySet="TABLEFOO">
<cs:EndProperty Name="TABLEFOO">
<cs:ScalarProperty Name="ID" ColumnName="ID" />
</cs:EndProperty>
<cs:EndProperty Name="TableBar">
<cs:ScalarProperty Name="ID" ColumnName="BAR_ID" />
</cs:EndProperty>
<cs:Condition ColumnName="BAR_ID" IsNull="false" />
</cs:AssociationSetMapping>
<cs:FunctionImportMapping FunctionImportName="SPBarFromFoo"
FunctionName="My.Namespace.Entities.Store.SP_BAR_FROM_FOO" />
End of Mapping section, end of Runtime declarations
</cs:EntityContainerMapping>
</cs:Mapping>
</edmx:Mappings>
</edmx:Runtime>
The rest of the edmx file contains the edmx:Designer section with layout information (shapes, connectors).
Leave a Comment » |
Entity Framework, Visual Studio, XML |
Permalink
Posted by devio
October 4, 2009
The Entity Designer of Visual Studio 2008 stores its data in an XML file with the extension .edmx. In the first part of this series I covered the Storage Model.
The Conceptual Model describes the EntitySets, Entities, AssociationSets and Associations as .Net classes and attributes in the xmlns:edm and xmlns:a schemas
- xmlns:edm=”http://schemas.microsoft.com/ado/2006/04/edm”
- xmlns:a=”http://schemas.microsoft.com/ado/2006/04/codegeneration”
<edmx:ConceptualModels>
<edm:Schema Namespace="My.Namespace.Entities" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<edm:EntityContainer Name="MyEntities">
<edm:EntitySet Name="TableFooSet" EntityType="My.Namespace.Entities.TableFoo" />
<edm:AssociationSet Name="FK_TABLEFOO_TABLEBAR" Association="My.Entities.FK_TABLEFOO_TABLEBAR">
<edm:End Role="TableBar" EntitySet="TableBarSet" />
<edm:End Role="TableFoo" EntitySet="TableFooSet" />
</edm:AssociationSet>
<edm:FunctionImport Name="SPBarFromFoo">
<edm:Parameter Name="FooID" Mode="In" Type="Int32" />
<edm:Parameter Name="BarID" Mode="InOut" Type="Int32" />
</edm:FunctionImport>
</edm:EntityContainer>
The Entity Container lists all sets. Then the entity description is listed in terms of Properties (columns) and Navigational Properties (foreign keys). NavigationalProperties are present in both tables of a foreign key relation:
<edm:EntityType Name="TableFoo">
<edm:Key>
<edm:PropertyRef Name="ID" />
</edm:Key>
<edm:Property Name="ID" Type="Int32" Nullable="false" />
<edm:Property Name="Serial" Type="String" Nullable="false"
MaxLength="20" Unicode="true" FixedLength="false" />
<edm:NavigationProperty Name="Bar" Relationship="My.Namespace.Entities.FK_TABLEFOO_TABLEBAR"
FromRole="TableFoo" ToRole="TableBar" />
</edm:EntityType>
<edm:Association Name="FK_TABLEFOO_TABLEBAR">
<edm:End Type="My.Namespace.Entities.TableBar" Role="TABLEBAR"
Multiplicity="1" />
<edm:End Type="My.Namespace.Entities.TableFoo" Role="TABLEFOO"
Multiplicity="*" />
</edm:Association>
The xmlns:a schema is used if property getter or setter have been assigned non-public visibility:
<edm:NavigationProperty Name="TABLEBAR"
Relationship="My.Namespace.Entities.FK_TABLEBAR_TABLEBLAH"
FromRole="TABLEBLAH" ToRole="TABLEBAR"
a:GetterAccess="Private" a:SetterAccess="Private" />
The end of the Conceptual Model
</edm:Schema>
</edmx:ConceptualModels>
2 Comments |
Entity Framework, SQL Server, Visual Studio |
Permalink
Posted by devio
October 2, 2009
The Entity Designer of Visual Studio 2008 stores its data in an XML file with the extension .edmx.
The file contains the Storage Model, the Conceptual Model, and Mappings between both models, and also layout information of the diagram. (The inclusion of layout data in a model file is really a conceptual mess).
Each section has its one or more XML namespaces. The ones I found necessary for parsing the XML data are:
- xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”
- xmlns:edmx=”http://schemas.microsoft.com/ado/2007/06/edmx”
- xmlns:store=”http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator”
- xmlns:ssdl=”http://schemas.microsoft.com/ado/2006/04/edm/ssdl”
- xmlns:cs=”urn:schemas-microsoft-com:windows:storage:mapping:CS”
- xmlns:edm=”http://schemas.microsoft.com/ado/2006/04/edm”
- xmlns:a=”http://schemas.microsoft.com/ado/2006/04/codegeneration”
This is the hierarchical structure of edmx. The first part describes the Storage Model which contains the selected objects from a SQL Server database: Tables, Views, Stored Procedures.
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx >
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<ssdl:Schema Namespace="My.Namespace.Entities.Store">
<ssdl:EntityContainer Name="MyEntitiesStoreContainer">
<ssdl:EntitySet Name="MY_TABLE_NAME"
EntityType="My.Namespace.Entities.Store.MY_TABLE_NAME"
store:Type="Tables" Schema="dbo" />
<ssdl:EntitySet Name="MY_VIEW_NAME"
EntityType="My.Namespace.Entities.Store.MY_VIEW_NAME"
store:Type="Views" store:Schema="dbo"
store:Name="MY_VIEW_NAME">
<ssdl:DefiningQuery>SELECT FOO FROM BAR
</ssdl:DefiningQuery>
</ssdl:EntitySet>
The foreign keys are listed as Association Sets:
<ssdl:AssociationSet Name="FK_TABLEFOO_TABLEBAR"
Association="My.Namespace.Entities.Store.FK_TABLEFOO_TABLEBAR">
<ssdl:End Role="TABLEBAR" EntitySet="TABLEBAR" />
<ssdl:End Role="TABLEFOO" EntitySet="TABLEFOO" />
</ssdl:AssociationSet>
</ssdl:EntityContainer>
After the Entity Container, all Entity Types and Associations are declared with their names and attributes:
<ssdl:EntityType Name="TABLEFOO">
<ssdl:Key>
<ssdl:PropertyRef Name="ID" />
</ssdl:Key>
<ssdl:Property Name="ID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
<ssdl:Property Name="NAME" Type="nvarchar" Nullable="false" MaxLength="150" />
<ssdl:Property Name="BAR_ID" Type="int" Nullable="true" />
</ssdl:EntityType>
<ssdl:Association Name="FK_TABLEFOO_TABLEBAR">
<ssdl:End Role="TABLEBAR" Type="My.Namespace.Entities.Store.TABLEBAR"
Multiplicity="1" />
<ssdl:End Role="TABLEFOO" Type="My.Namespace.Entities.Store.TABLEFOO"
Multiplicity="*" />
<ssdl:ReferentialConstraint>
<ssdl:Principal Role="TABLEBAR">
<ssdl:PropertyRef Name="ID" />
</ssdl:Principal>
<ssdl:Dependent Role="TABLEFOO">
<ssdl:PropertyRef Name="BAR_ID" />
<ssdl:/Dependent>
</ssdl:ReferentialConstraint>
</ssdl:Association>
Stored Procedures can also be included in the Storage Model:
<ssdl:Function Name="SP_BAR_FROM_FOO" Aggregate="false" BuiltIn="false"
NiladicFunction="false" IsComposable="false"
ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<ssdl:Parameter Name="FOO_ID" Type="int" Mode="In" />
<ssdl:Parameter Name="BAR_ID" Type="int" Mode="InOut" />
</ssdl:Function>
The end of the Storage Model section
</ssdl:Schema>
</edmx:StorageModels>
2 Comments |
Entity Framework, SQL Server, Visual Studio |
Permalink
Posted by devio