Schema Definitions Of EDM In Entity Framework

April 26, 2008

no comments

Schema Definitions Of EDM In Entity Framework


On the previous post about the entity framework I wrote about the
entity data model (EDM) and explained how to add a one to one mapping
model to your application.
Today I’m going to explain a little about the bits and bites of the new
XML schema types which describe the models.


The Schema Types
The EDM is divided into three models (as explained in my previous post) – the
conceptual, the mapping and the logical model.
Every model has it’s own XML schema type:



  • Store Schema Definition Language (.ssdl) schema type
    The schema describes the database tables and relations between them.

  • Mapping Specification Language (.msl) schema type
    The schema describes the mapping between the conceptual model (csdl)
    and the logical model (ssdl).

  • Conceptual Schema Definition Language (.csdl) schema type
    The schema describes the objects and their relations.

The Example Model
Lets look at a picture of the example I’m going to show:

EDM Example

I use two tables from a database – Companies and Employees.
The example will help me explain the relevant parts in the schema files of the EDM.
You should note that the example is a simple one to one mapping.


Store Metadata – SSDL Example



<?xml version=1.0 encoding=utf-8?>


<Schema Namespace=CompaniesModel.Store Alias=Self 
  ProviderManifestToken=09.00.3054
  xmlns=http://schemas.microsoft.com/ado/2006/04/edm/ssdl>


  <EntityContainer Name=dbo>


    <EntitySet Name=Companies EntityType=CompaniesModel.Store.Companies />


    <EntitySet Name=Employees EntityType=CompaniesModel.Store.Employees />


    <AssociationSet Name=FK_Employees_Companies
      
Association=CompaniesModel.Store.FK_Employees_Companies>


      <End Role=Companies EntitySet=Companies />


      <End Role=Employees EntitySet=Employees />


    </AssociationSet>


  </EntityContainer>


  <EntityType Name=Companies>


    <Key>


      <PropertyRef Name=CompanyID />


    </Key>


    <Property Name=CompanyID Type=bigint Nullable=false
      
StoreGeneratedPattern=Identity />


    <Property Name=CompanyName Type=nvarchar MaxLength=100 />


    <Property Name=CompanyAddress Type=nvarchar MaxLength=100 />


    <Property Name=CompanyPhone Type=nvarchar MaxLength=50 />


  </EntityType>


  <EntityType Name=Employees>


    <Key>


      <PropertyRef Name=EmpolyeeID />


    </Key>


    <Property Name=EmpolyeeID Type=bigint Nullable=false
      
StoreGeneratedPattern=Identity />


    <Property Name=CompanyID Type=bigint />


    <Property Name=EmployeefirstName Type=nvarchar MaxLength=50 />


    <Property Name=EmployeeLastName Type=nvarchar MaxLength=50 />


    <Property Name=EmployeeJobTitle Type=int />


    <Property Name=EmployeePhone Type=nvarchar MaxLength=50 />


  </EntityType>


  <Association Name=FK_Employees_Companies>


    <End Role=Companies Type=CompaniesModel.Store.Companies
      
Multiplicity=0..1 />


    <End Role=Employees Type=CompaniesModel.Store.Employees
      
Multiplicity=* />


    <ReferentialConstraint>


      <Principal Role=Companies>


        <PropertyRef Name=CompanyID />


      </Principal>


      <Dependent Role=Employees>


        <PropertyRef Name=CompanyID />


      </Dependent>


    </ReferentialConstraint>


  </Association>


</Schema>


The schema define the namespace to use for the store definition which is
CompaniesModel.Store.
Then you can see that the schema is built from three main elements –
the EntityContainer element, the EntityType elements and the Association elements.


The EntityContainer is the definition of all the elements and their associations.
Every EntityType is reference by an EntitySet and every Association is referenced by
AssociationSet. You can see that the association set is using the entity sets defined
earlier and also using the Roles which will be defined later in the Association elements.


The EntityType elements are the definition of every table in the database.
Every EntityType has a Key element that describe the primary key of the current
element. Also every EntityType has Property elements that describe the fields in the
database. For every Property there is a set of attributes which include it’s name and
database type and also constraints like MaxLength or Nullable which are taken
from the database.


The Association elements are the definition of the foreign keys between the tables
in the database. Every Association define the end points of the foreign key by
using the End elements. Every End element is built from its Role, its type which is the
table it’s connected to and its Multiplicity which define the the number of entities
that can exist on each side of a relationship (cardinality).
There is also the ReferentialConstraint that define the fields that are used in the
association. The ReferentialConstraint is built from Dependent elements which describe
the property that is used from the EntityType.


Mapping Specification – MSL Example



<?xml version=1.0 encoding=utf-8?>


<Mapping Space=C-S xmlns=urn:schemas-microsoft-com:windows:storage:mapping:CS>


  <EntityContainerMapping StorageEntityContainer=dbo
    
CdmEntityContainer=CompaniesEntities>


    <EntitySetMapping Name=Companies>


      <EntityTypeMapping TypeName=IsTypeOf(CompaniesModel.Companies)>


        <MappingFragment StoreEntitySet=Companies>


          <ScalarProperty Name=CompanyID ColumnName=CompanyID />


          <ScalarProperty Name=CompanyName ColumnName=CompanyName />


          <ScalarProperty Name=CompanyAddress ColumnName=CompanyAddress />


          <ScalarProperty Name=CompanyPhone ColumnName=CompanyPhone />


        </MappingFragment>


      </EntityTypeMapping>


    </EntitySetMapping>


    <EntitySetMapping Name=Employees>


      <EntityTypeMapping TypeName=IsTypeOf(CompaniesModel.Employees)>


        <MappingFragment StoreEntitySet=Employees>


          <ScalarProperty Name=EmpolyeeID ColumnName=EmpolyeeID />


          <ScalarProperty Name=EmployeefirstName ColumnName=EmployeefirstName />


          <ScalarProperty Name=EmployeeLastName ColumnName=EmployeeLastName />


          <ScalarProperty Name=EmployeeJobTitle ColumnName=EmployeeJobTitle />


          <ScalarProperty Name=EmployeePhone ColumnName=EmployeePhone />


        </MappingFragment>


      </EntityTypeMapping>


    </EntitySetMapping>


    <AssociationSetMapping Name=FK_Employees_Companies 
         TypeName=CompaniesModel.FK_Employees_Companies StoreEntitySet=Employees>


      <EndProperty Name=Companies>


        <ScalarProperty Name=CompanyID ColumnName=CompanyID />


      </EndProperty>


      <EndProperty Name=Employees>


        <ScalarProperty Name=EmpolyeeID ColumnName=EmpolyeeID />


      </EndProperty>


      <Condition ColumnName=CompanyID IsNull=false />


    </AssociationSetMapping>


  </EntityContainerMapping>


</Mapping>


The msl schema define the relation between the ssdl schema and the csdl schema.
The main element is the EntityContainerMapping which connect the ssdl container
(the StorageEntityContainer) and the csdl container (the CdmEntityContainer).
The mapping between tables and entities are based on the EntitySetMapping elements.
The mapping between foreign keys and entity relations are based on the
AssociationSetMapping elements.


The EntitySetMapping element has a main element which is the EntityTypeMapping.
The EntityTypeMapping has a type name which was described in the csdl file. That
type name is mapped to the one or more MappingFragment which describe the store entity set.
This way of definition enable us to map entities to more then one table as will be shown
in the next posts I’m going to write.
Also there is a mapping for every property in the csdl to its property in the store
definition by the ScalarProperty element.


The AssociationSetMapping element maps the store entity set which was defined in the
ssdl file to the relation that was defined in the csdl file. The TypeName attribute describe
the name of the csdl relation and the StoreEntitySet describe the name of the
ssdl association. Every EndProperty element is the mapping between the End elements
in the ssdl to the End elements in the csdl. The Condition is the constraint which in our case
CompanyID shouldn’t be null in order for the association to be valid.


Conceptual Schema – CSDL Example



<?xml version=1.0 encoding=utf-8?>


<Schema Namespace=CompaniesModel Alias=Self 
  xmlns=http://schemas.microsoft.com/ado/2006/04/edm>


  <EntityContainer Name=CompaniesEntities>


    <EntitySet Name=Companies EntityType=CompaniesModel.Companies />


    <EntitySet Name=Employees EntityType=CompaniesModel.Employees />


    <AssociationSet Name=FK_Employees_Companies
       Association=CompaniesModel.FK_Employees_Companies>


      <End Role=Companies EntitySet=Companies />


      <End Role=Employees EntitySet=Employees />


    </AssociationSet>


  </EntityContainer>


  <EntityType Name=Companies>


    <Key>


      <PropertyRef Name=CompanyID />


    </Key>


    <Property Name=CompanyID Type=Int64 Nullable=false />


    <Property Name=CompanyName Type=String MaxLength=100 />


    <Property Name=CompanyAddress Type=String MaxLength=100 />


    <Property Name=CompanyPhone Type=String MaxLength=50 />


    <NavigationProperty Name=Employees 
       Relationship=CompaniesModel.FK_Employees_Companies
      
FromRole=Companies ToRole=Employees />


  </EntityType>


  <EntityType Name=Employees>


    <Key>


      <PropertyRef Name=EmpolyeeID />


    </Key>


    <Property Name=EmpolyeeID Type=Int64 Nullable=false />


    <Property Name=EmployeefirstName Type=String MaxLength=50 />


    <Property Name=EmployeeLastName Type=String MaxLength=50 />


    <Property Name=EmployeeJobTitle Type=Int32 />


    <Property Name=EmployeePhone Type=String MaxLength=50 />


    <NavigationProperty Name=Companies
       Relationship=CompaniesModel.FK_Employees_Companies
      
FromRole=Employees ToRole=Companies />


  </EntityType>


  <Association Name=FK_Employees_Companies>


    <End Role=Companies Type=CompaniesModel.Companies
      
Multiplicity=0..1 />


    <End Role=Employees Type=CompaniesModel.Employees
      
Multiplicity=* />


  </Association>


</Schema>


The schema describe the namespace for the conceptual model which is CompaniesModel.
As in the ssdl schema the csdl schema is divided into three main elements –
the EntityContainer element, the EntityType elements and the Association elements.


The EntityContainer is the definition of all the entities and their relations.
Every EntityType is reference by an EntitySet and every Association is referenced by
AssociationSet. You can see that the association set is using the entity sets defined
earlier and also using the Roles which will be defined later in the Association elements.


The EntityType element is the definition of every entity.
Every EntityType has a Key element that describe the primary property of the current
element (The entity ID). Also every EntityType has Property elements that describe its
properties. For every Property there is a set of attributes which include it’s name and
.Net type and also constraints like MaxLength or Nullable.
There is an element called NavigationProperty that describe relations between
entities. In our example every employee works in a company which is another entity
in the schema. The FromRole and ToRole describe the direction of the relation which
will be described in the Association element (one to one, one to many, many to many).


The Association element is the definition of the relations of the entities.
Every Association define the end points of the relation by using the End elements.
Every End element is built from its Role, its type which is the
entity it’s connected to and its Multiplicity which define the the number of entities
that can exist on each side of a relationship (cardinality).


Summary
Let sum up what I showed in the post.
I described the three models which construct the EDM and the XML schema types.
I showed simple examples for every schema file and described important key
features in the files. I didn’t show stored procedure mapping or mapping of one entity
to many tables. These subjects will be explained in the next posts.
 
As you can understand, the mission of manually writing the schema files is very
complicated but if you want to understand the entity framework you should be
familiar with them.
In the next post about the entity framework I’m going to explain how to work with
other features the framework provides. 

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*