The Entity Framework facilitates the development and conceptual use of application models
for development instead of directly using relational storage schema. The benefits
of conceptual programming models are fewer amounts of code and maintenance.
The ADO .NET Entity Framework provides the following benefits:
- The Entity framework may help to remove hard-coded dependencies on storage schema.
- EF provides mapping between conceptual
model and storage schema; it helps to change storage schema without effecting
application code.
- Multiple conceptual models can be mapped
to a single storage schema.
- EF also supports LINQ for query; again the
conceptual model helps us to provide compile time validation.
Entity Framework applications and services are
XML- based language information divided into three parts:
- Conceptual Model (Conceptual schema
definition language (CSDL)).
- Storage Model (Store schema definition
language (SSDL))
- Mapping between Conceptual and Storage
Model (Mapping specification language (MSL))
These three parts of the model can be generated
automatically by the Entity Data Model Tool. This tool generates the model, mapping
information as well as data classes from existing database schema. Developers can
change the model using graphically change conceptual model with the help of the Entity
Designer or change it manually by changing XML tags.
The EDM Generator (EdmGen.exe) is a command-line tool used to generate a
simple conceptual model with a one-to-one mapping between entities and tables in
a data source. It can be used to validate a conceptual model and generate the
data classes.
Before proceeding we must know the terminology of the Entity Framework. For that,
refer to the following link.
http://msdn.microsoft.com/en-us/library/bb387161.aspx
Conceptual Model
The Conceptual model is also called Conceptual Schema Definition Language (CSDL) and is a XML
based language. CSDL contains the entity type and each
entity type has a name, a key (for uniquely identifying instances), and a set
of properties. The Data Type of the properties are either a simple type (like int,
string etc.) or complex type (like class, object etc.). XML attributes may also
contain nullable or a default value. Associations define the relationships
between entities.
Entity Relation in GUI.
Finally, the Conceptual Model (CSDL) contains an Entity Set (Logical Name of Entity),
Properties, keys (Primary Key) and associations.
Refer to the following figure to understand conceptual Model in detail.
Storage Model
Storage model is also called a Storage Schema Definition Language (SSDL) and is also a XML based
language. SSDL contain entity type (Actual Table name in Database in this case)
and each entity type has a key (for Primary Key define in Database for that
table), and a set of properties (Column of that database table). Properties of
entity type contain name and type of column and nullable information.
Mapping Model
Mapping model is also called Mapping Specification Language (MSL) and is a XML based
language. MSL is a map of a conceptual model to a storage model.
The EF compiles conceptual and storage model metadata, with mapping between
Model and pair of entity SQL statements called "Client View". These views are
generated invoked either at design time or runtime when query called first time
in conceptual Model.
When the query is executed, its results are parsed and converted into a canonical
command tree. This canonical command tree represents insert, update, delete and
select commands. All subsequent processing is performed on the command tree that
means communication between System.Data.EntityClient and data provider like
System.Data.SqlClient.
Update EDMX
You can generate an EDM (Entity Data Model) using a database as a starting point
or modify the XML manually or update it using a modeling tool.
You may update an edmx by generating it from the data base, but in the case where the model is very
complicated and your conceptual model is totally different from the storage model, you must update your edmx manually.
First, we learn how we update the model using a builtin tool.
The first step is to open your EDMX in the GUI and right-click on EDMX and select "Update
Model from Data Base."
From this screen you may add multiple tables, views and stored procedures. And click
on the "Finish" button; it automatically generates a conceptual model and storage model
in a XML file.
Update EDMX Manually
If you have large databases and your entity model is very customized then it is necessary to update the EDMX manually.
To update the EDMX manually, the first step is to open the EDMX with the XML Editor in Visual
Studio.
Now we update the conceptual model, storage model and mapping model step by step.
The list of items must be updated to model work perfect (check list for updating model).
- Conceptual Model
a. New Entity Type.
b. Association (FOREIGN KEY).
c. Entity set in Entity container.
d. Add Association in Entity Container.
- Storage Model
a. New Entity Type.
b. Association (FOREIGN KEY).
c. Entity set in Entity container.
d. Add Association in Entity Container.
- Mapping Model
a. Mapping Between Conceptual Model and Storage Model
Conceptual Model
Adding New Entity Type
<Schema
Namespace="AdventureWorksModel"
Alias="Self"
xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
...
...
...
<EntityType
Name="EmployeeAddress">
<Key>
<PropertyRef
Name="AddressId"
/>
</Key>
<Property
Type="Int32"
Name="AddressId"
Nullable="false"
/>
<Property
Type="Int32"
Name="EmployeeId"
/>
<Property
Type="String"
Name="AddressLine1"
MaxLength="50"
FixedLength="false"
Unicode="false"
/>
<Property
Type="String"
Name="AddressLine2"
MaxLength="50"
FixedLength="false"
Unicode="false"
/>
<Property
Type="String"
Name="AddressLine3"
MaxLength="50"
FixedLength="false"
Unicode="false"
/>
<Property
Type="String"
Name="City"
MaxLength="50"
FixedLength="false"
Unicode="false"
/>
<Property
Type="String"
Name="Pincode"
MaxLength="10"
FixedLength="false"
Unicode="false"
/>
<Property
Type="String"
Name="State"
MaxLength="50"
FixedLength="false"
Unicode="false"
/>
<Property
Type="String"
Name="Country"
MaxLength="50"
FixedLength="false"
Unicode="false"
/>
<NavigationProperty
Name="Employee"
Relationship="AdventureWorksModel.FK_Address_Employees"
FromRole="EmployeeAddress"
ToRole="Employee"
/>
</EntityType>
....
....
....
</Schema>
Adding association
<Schema
Namespace="AdventureWorksModel"
Alias="Self"
xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
....
....
....
<Association
Name="FK_Address_Employees">
<End
Type="AdventureWorksModel.Employee"
Role="Employee"
Multiplicity="0..1"
/>
<End
Type="AdventureWorksModel.EmployeeAddress"
Role="EmployeeAddress"
Multiplicity="*"
/>
<ReferentialConstraint>
<Principal
Role="Employee">
<PropertyRef
Name="EmployeeId"
/>
</Principal>
<Dependent
Role="EmployeeAddress">
<PropertyRef
Name="EmployeeId"
/>
</Dependent>
</ReferentialConstraint>
</Association>
....
....
....
</Schema>
Adding Entity Set in "Entity Container"
<Schema
Namespace="AdventureWorksModel"
Alias="Self"
xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer
Name="AdventureWorksEntities"
annotation:LazyLoadingEnabled="true">
....
....
<EntitySet
Name="EmployeeAddresses"
EntityType ="AdventureWorksModel.
EmployeeAddress" />
....
....
</EntityContainer>
....
....
</Schema>
Adding Association in "Entity Container".
<Schema
Namespace="AdventureWorksModel"
Alias="Self"
xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation"
xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer
Name="AdventureWorksEntities"
annotation:LazyLoadingEnabled="true">
....
....
<EntitySet
Name="EmployeeAddresses"
EntityType ="AdventureWorksModel.
EmployeeAddress" />
<AssociationSet
Name="FK_Address_Employees"
Association="AdventureWorksModel.FK_Address_Employees">
<End
Role="Employee"
EntitySet="Employees"
/>
<End
Role="EmployeeAddress"
EntitySet="EmployeeAddresses"
/>
</AssociationSet>
....
....
</EntityContainer>
....
....
</Schema>
Storage Model
Adding New Entity Type
<Schema
Namespace="AdventureWorksModel.Store"
Alias="Self"
Provider="System.Data.SqlClient"
ProviderManifestToken="2008"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
....
....
<EntityType
Name="EmployeeAddress">
<Key>
<PropertyRef
Name="AddressId"
/>
</Key>
<Property
Name="AddressId"
Type="int"
Nullable="false"
/>
<Property
Name="EmployeeId"
Type="int"
/>
<Property
Name="AddressLine1"
Type="varchar"
MaxLength="50"
/>
<Property
Name="AddressLine2"
Type="varchar"
MaxLength="50"
/>
<Property
Name="AddressLine3"
Type="varchar"
MaxLength="50"
/>
<Property
Name="City"
Type="varchar"
MaxLength="50"
/>
<Property
Name="Pincode"
Type="varchar"
MaxLength="10"
/>
<Property
Name="State"
Type="varchar"
MaxLength="50"
/>
<Property
Name="Country"
Type="varchar"
MaxLength="50"
/>
</EntityType>
....
....
</Schema>
Adding association
<Schema
Namespace="AdventureWorksModel.Store"
Alias="Self"
Provider="System.Data.SqlClient"
ProviderManifestToken="2008"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
....
....
<Association
Name="FK_Address_Employees">
<End
Role="Employees"
Type="AdventureWorksModel.Store.Employees"
Multiplicity="0..1"
/>
<End
Role="EmployeeAddress"
Type="AdventureWorksModel.Store.EmployeeAddress"
Multiplicity="*"
/>
<ReferentialConstraint>
<Principal
Role="Employees">
<PropertyRef
Name="EmployeeId"
/>
</Principal>
<Dependent
Role="EmployeeAddress">
<PropertyRef
Name="EmployeeId"
/>
</Dependent>
</ReferentialConstraint>
</Association>
....
....
</Schema>
Adding Entity Set in "Entity Container"
<Schema
Namespace="AdventureWorksModel.Store"
Alias="Self"
Provider="System.Data.SqlClient"
ProviderManifestToken="2008"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
....
....
<EntityContainer
Name="AdventureWorksModelStoreContainer">
....
....
<EntitySet
Name="EmployeeAddress"
EntityType="AdventureWorksModel.Store.EmployeeAddress"
store:Type="Tables"
Schema="dbo"
/>
....
....
</EntityContainer>
....
....
</Schema>
Adding Association in "Entity Container"
<Schema
Namespace="AdventureWorksModel.Store"
Alias="Self"
Provider="System.Data.SqlClient"
ProviderManifestToken="2008"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
....
....
<EntityContainer
Name="AdventureWorksModelStoreContainer">
....
....
<EntitySet
Name="EmployeeAddress"
EntityType="AdventureWorksModel.Store.EmployeeAddress"
store:Type="Tables"
Schema="dbo"
/>
<AssociationSet
Name="FK_Address_Employees"
Association="AdventureWorksModel.Store.FK_Address_Employees">
<End
Role="Employees"
EntitySet="Employees"
/>
<End
Role="EmployeeAddress"
EntitySet="EmployeeAddress"
/>
</AssociationSet>
....
....
</EntityContainer>
....
....
</Schema>
Mapping Model
<Mapping
Space="C-S"
xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
<EntityContainerMapping
StorageEntityContainer="AdventureWorksModelStoreContainer"
CdmEntityContainer="AdventureWorksEntities">
....
....
<EntitySetMapping
Name="EmployeeAddresses">
<EntityTypeMapping
TypeName="AdventureWorksModel.EmployeeAddress">
<MappingFragment
StoreEntitySet="EmployeeAddress">
<ScalarProperty
Name="Country"
ColumnName="Country"
/>
<ScalarProperty
Name="State"
ColumnName="State"
/>
<ScalarProperty
Name="Pincode"
ColumnName="Pincode"
/>
<ScalarProperty
Name="City"
ColumnName="City"
/>
<ScalarProperty
Name="AddressLine3"
ColumnName="AddressLine3"
/>
<ScalarProperty
Name="AddressLine2"
ColumnName="AddressLine2"
/>
<ScalarProperty
Name="AddressLine1"
ColumnName="AddressLine1"
/>
<ScalarProperty
Name="EmployeeId"
ColumnName="EmployeeId"
/>
<ScalarProperty
Name="AddressId"
ColumnName="AddressId"
/>
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
....
....
</EntityContainerMapping>
</Mapping>
In the next article we will learn about TPH (Table Per Hierarchy) and TPT
(Table Per Type) and how to add it to an EDMX.
Reference
http://msdn.microsoft.com/en-us/library/bb399567.aspx