Entity Data Model in Entity Framework

Entity Data Model (EDM) of Entity Framework Database First Approach

In this article, I am going to discuss the Entity Data Model (EDM) of Entity Framework Database First Approach in detail. We are going to work with the same example that we created in our previous article. Please read our previous article before proceeding to this article where we created the required database tables, views, and stored procedure with test data as well as we also discussed the step by step procedure to interact with the database using Entity Framework Database First Approach.

Entity Data Model (EDM) in Entity Framework:

The Entity Data Model (EDM) in Entity Framework is an extended version of the Entity-Relationship model which specifies the conceptual model of the data using various modeling techniques. It also refers to a set of concepts that describe data structure, regardless of its stored form.

EDM supports a set of primitive data types that define properties in a conceptual model. We need to consider 3 core parts that form the basis for Entity Framework and collectively it is known as the Entity Data Model. Following are the three core parts of EDM.

  1. The Storage Schema Definition Model
  2. The Conceptual Schema Definition Model
  3. The Mapping Model (Conceptual – Storage Mapping)

Entity Data Model (EDM) of Entity Framework Database First Approach

The Storage Schema Model

The Storage Schema Model also called as Storage Schema Definition Layer (SSDL) represents the schematic representation of the backend data store.

The Conceptual Schema Model

The Conceptual Schema Model also called Conceptual Schema Definition Layer (CSDL) is the real entity model, against which we write our queries.

The Mapping Model (Conceptual – Storage Mapping)

The mapping Layer is just a mapping between the Conceptual model and the Storage model. The logical schema and its mapping with the physical schema are represented as an EDM.

  1. Visual Studio also provides an Entity Designer, for the visual creation of the EDM and the mapping specification.
  2. The output of the tool is the XML file (*.edmx) specifying the schema and the mapping.
  3. Edmx file contains Entity Framework metadata artifacts.
How to see the Schema Definition of EDM?

In order to see the three parts of the Entity Data Model i.e. Conceptual schema (CSDL), Storage schema (SSDL), and Mapping Schema (MSL), you need to open the EDM designer in XML view. To do so, Right-click on StudentDataModel.edmx -> click ‘Open with..‘, option as shown below.

How to see the Schema Definition of EDM?

This will open the following popup window. Here, you need to select ‘XML (text) Editor‘ and click on the OK button as shown below.

Entity Data Model (EDM)

The Visual Studio cannot display the model in both Design view and in XML format at the same time. So, it will ask you with one popup to close the edmx file, just click Yes as shown below.

Entity Data Model (EDM) of Entity Framework

Once you click Yes, it will open the XML format view. You can see the following XML view by toggling all outlining as shown below.

Entity Data Model (EDM) of Entity Framework

You can see the SSDL content, the CSDL content, and the C-S Mapping content here. If you expand the SSDL and CSDL, each one has some common XML node under each schema node. You don’t need to edit the XML data because this can be accomplished easier in the Model Browser.

Schema Definition Language

ADO.NET Entity Framework uses an XML based Data Definition Language called Schema Definition Language (SDL) to define the EDM Schema.

  1. The SDL defines the Simple Types as similar to other primitive types, including String, Int32, Double, Decimal, and DateTime, among others.
  2. An Enumeration, which defines a map of primitive values and names, is also considered a simple type.
  3. Enumerations are supported from framework version 5.0 onwards only.
  4. Complex Types are created from an aggregation of other types. A collection of properties of these types define an Entity Type.

The data model primarily has three key concepts to describe data structure −

  1. Entity type
  2. Association type
  3. Property
Entity Type

The entity type is the fundamental building block for describing the structure of data in EDM.

  1. In a conceptual model, entity types are constructed from properties and describe the structure of top-level entities, such as a Students, Course, Teacher, StudentAddress and Standard in a business application.
  2. An entity represents a specific object such as a specific Student or Course or Teacher.
  3. Each entity must have a unique entity key within an entity set. An entity set is a collection of instances of a specific entity type. Entity sets (and association sets) are logically grouped in an entity container.
  4. Inheritance is supported with entity types, that is, one entity type can be derived from another.
Association Type

It is another fundamental building block for describing relationships in EDM. In a conceptual model, an association represents a relationship between two entity types such as Student and Course.

  1. Every association has two association ends that specify the entity types involved in the association.
  2. Each association end also specifies an association end multiplicity that indicates the number of entities that can be at that end of the association.
  3. An association end multiplicity can have a value of one (1), zero or one (0..1), or many (*).
  4. Entities at one end of an association can be accessed through navigation properties, or through foreign keys if they are exposed on an entity type.
Property

Entity types contain properties that define their structure and characteristics. For example, a Student entity type may have properties such as Student Id, Name, etc.

A property can contain primitive data (such as a string, an integer, or a Boolean value), or structured data (such as a complex type).

Entity-Table Mapping in Entity Framework

The point that you need to remember is each entity in EDM is mapped with the database table. You can check the entity-table mapping by right-clicking on any entity in the EDM designer and then select Table Mapping. Let see the Student entity mapping. So, right-click on the Student Entity in the EDM Design and select Table Mapping which shows the following.

Entity-Table Mapping in Entity Framework

Note: If you change any property name of the entity from designer then the table mapping would reflect that change automatically.

Context and Entity Classes

Every Entity Data Model (EDM) generates one context class for the database and an entity class for each database table and view. In order to verify this, expand the .edmx file in the solution explorer and open two important files i.e. <EDM Name>.Context.tt and <EDM Name>.tt, as shown in the below image.

Context and Entity Classes in Entity Data Model

StudentDataModel.Context.tt: 

This T4 template file generates a context class whenever you change the Entity Data Model (.edmx file). You can see the context class file by expanding StudentDataModel.Context.tt. The context class resides in the <EDM Name>.context.cs file. In our case the context class file name is StudentDataModel.Context.cs. The default context class name is <DB Name>Entities. For example, the context class name for EF_Demo_DB is EF_Demo_DBEntities and derived from the DBContext class as shown below.

namespace DBFirstApproach
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Data.Entity.Core.Objects;
    using System.Linq;
    
    public partial class EF_Demo_DBEntities : DbContext
    {
        public EF_Demo_DBEntities()
            : base("name=EF_Demo_DBEntities")
        {
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public virtual DbSet<Course> Courses { get; set; }
        public virtual DbSet<Standard> Standards { get; set; }
        public virtual DbSet<Student> Students { get; set; }
        public virtual DbSet<StudentAddress> StudentAddresses { get; set; }
        public virtual DbSet<Teacher> Teachers { get; set; }
        public virtual DbSet<vwStudentCourse> vwStudentCourses { get; set; }
    
        public virtual int spDeleteStudent(Nullable<int> studentId)
        {
            var studentIdParameter = studentId.HasValue ?
                new ObjectParameter("StudentId", studentId) :
                new ObjectParameter("StudentId", typeof(int));
    
            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("spDeleteStudent", studentIdParameter);
        }
    
        public virtual ObjectResult<spGetCoursesByStudentId_Result> spGetCoursesByStudentId(Nullable<int> studentID)
        {
            var studentIDParameter = studentID.HasValue ?
                new ObjectParameter("StudentID", studentID) :
                new ObjectParameter("StudentID", typeof(int));
    
            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<spGetCoursesByStudentId_Result>("spGetCoursesByStudentId", studentIDParameter);
        }
    
        public virtual ObjectResult<Nullable<decimal>> spInsertStudent(Nullable<int> standardId, string firstName, string lastName)
        {
            var standardIdParameter = standardId.HasValue ?
                new ObjectParameter("StandardId", standardId) :
                new ObjectParameter("StandardId", typeof(int));
    
            var firstNameParameter = firstName != null ?
                new ObjectParameter("FirstName", firstName) :
                new ObjectParameter("FirstName", typeof(string));
    
            var lastNameParameter = lastName != null ?
                new ObjectParameter("LastName", lastName) :
                new ObjectParameter("LastName", typeof(string));
    
            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<decimal>>("spInsertStudent", standardIdParameter, firstNameParameter, lastNameParameter);
        }
    
        public virtual int spUpdateStudent(Nullable<int> studentId, Nullable<int> standardId, string firstName, string lastName)
        {
            var studentIdParameter = studentId.HasValue ?
                new ObjectParameter("StudentId", studentId) :
                new ObjectParameter("StudentId", typeof(int));
    
            var standardIdParameter = standardId.HasValue ?
                new ObjectParameter("StandardId", standardId) :
                new ObjectParameter("StandardId", typeof(int));
    
            var firstNameParameter = firstName != null ?
                new ObjectParameter("FirstName", firstName) :
                new ObjectParameter("FirstName", typeof(string));
    
            var lastNameParameter = lastName != null ?
                new ObjectParameter("LastName", lastName) :
                new ObjectParameter("LastName", typeof(string));
    
            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("spUpdateStudent", studentIdParameter, standardIdParameter, firstNameParameter, lastNameParameter);
        }
    }
}
StudentDataModel.tt: 

The StudentDataModel.tt is a T4 template file that generates entity classes for each Database table, views, stored procedure, and functions. Entity classes are POCO (Plain Old CLR Object) classes.

Entity Classes Classes:

The following code snippet shows the Student entity.

namespace DBFirstApproach
{
    using System;
    using System.Collections.Generic;
    
    public partial class Student
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Student()
        {
            this.Courses = new HashSet<Course>();
        }
    
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Nullable<int> StandardId { get; set; }
    
        public virtual Standard Standard { get; set; }
        public virtual StudentAddress StudentAddress { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Course> Courses { get; set; }
    }
}

The following code snippet shows the StudentAddress entity.

namespace DBFirstApproach
{
    using System;
    using System.Collections.Generic;
    
    public partial class StudentAddress
    {
        public int StudentId { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string Mobile { get; set; }
        public string Email { get; set; }
    
        public virtual Student Student { get; set; }
    }
}

The following code snippet shows the Course entity.

namespace DBFirstApproach
{
    using System;
    using System.Collections.Generic;
    
    public partial class Course
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Course()
        {
            this.Students = new HashSet<Student>();
        }
    
        public int CourseId { get; set; }
        public string CourseName { get; set; }
        public Nullable<int> TeacherId { get; set; }
    
        public virtual Teacher Teacher { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Student> Students { get; set; }
    }
}

You can check the other entities as well.

Database Views Classes:

The following code snippet shows the vwStudentCourse.

namespace DBFirstApproach
{
    using System;
    using System.Collections.Generic;
    
    public partial class vwStudentCourse
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int CourseId { get; set; }
        public string CourseName { get; set; }
    }
}

Note: The point that you need to understand here is for each database table and view, it creates an entity.

In the next article, I am going to discuss the Model Browser in Entity Framework. In this article, I try to explain the Entity Data Model (EDM) of Entity Framework Database First Approach and I hope you enjoyed this Entity Data Model (EDM) of Entity Framework Database First Approach article. Please give your valuable feedback and suggestions about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *