Schema Definitions Of EDM In Entity Framework

 

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.
 

source: http://blogs.microsoft.co.il/gilf/2008/04/10/getting-started-with-entity-framework/