Book Image

Mastering Entity Framework

By : Rahul Rajat Singh
Book Image

Mastering Entity Framework

By: Rahul Rajat Singh

Overview of this book

<p>Data access is an integral part of any software application. Entity Framework provides a model-based system that makes data access effortless for developers by freeing you from writing similar data access code for all of your domain models.</p> <p>Mastering Entity Framework provides you with a range of options when developing a data-oriented application. You’ll get started by managing the database relationships as Entity relationships and perform domain modeling using Entity Framework. You will then explore how you can reuse data access layer code such as stored procedures and table-valued functions, and perform various typical activities such as validations and error handling. You’ll learn how to retrieve data by querying the Entity Data Model and understand how to use LINQ to Entities and Entity SQL to query the Entity Data Model.</p>
Table of Contents (19 chapters)
Mastering Entity Framework
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Entity Framework Database First approach


This approach has been available since the first version of Entity Framework. In this approach, we start with an already existing database and start creating our EDM from the existing database. Let's try to see how this works using the Entity Framework Database First approach with our ToDo sample. To use the Entity Framework Database First approach, we have to add a new ADO.NET EDM to our project:

Add a new ADO.NET EDM

Let's start by defining a database for the ToDo application. Let's create a simple table that will keep a track of all the ToDo items:

A table schema for the sample ToDo application

The application requirements state that it should be possible to perform the following activities on the ToDos:

  • Read the list of ToDos

  • Create a ToDo item

  • Read a specific ToDo item

  • Update the status of a ToDo item

  • Delete a ToDo item

When we add the EDM, it asks us whether we want to create the conceptual model from the existing database, or if we want to create an empty model. For the Database First approach, we need to select an existing database. The following screenshot shows the wizard step that asks you to select the database:

ADO.NET EDM wizard step 1—generate from the database

Once we choose to add the EDM, we need to specify the database that should be used to create it. So, the next step in the wizard will ask you for the connection to the database. Let's see what this wizard step looks like:

ADO.NET EDM wizard step 2—select the database

Once the connection is successfully established, the wizard shows us all the tables, views, procedures, and functions that we will want to access from our application. Using this wizard, we can also choose to include the foreign key relations in our conceptual model and singularization of the model name, in case the table name is plural in our conceptual model:

ADO.NET EDM wizard step 3—select the schema elements to be included in the EDM

Once the conceptual model is created, the EDM will be created for use in our application. The application will create a .EDMX file that contains all the information about our conceptual entity model and its mapping to the database tables:

Visual Entity Designer showing the default model

We can modify the conceptual model and change the mapping using entity designer. Let's try to change the property ToDo1 to ToDoItem in our conceptual model. Note that only the class property has been changed, and not the column name:

Visual Entity Designer showing the customized model

If we open the EDMX file, we can find the following three sections:

  • Conceptual schema definition: This specifies how a strongly typed model for our conceptual model will be created:

    <edmx:ConceptualModels>
      <Schema Namespace="ToDoDBModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
      <EntityType Name="ToDo">
        <Key>
        <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Int32" Nullable="false" />
        <Property Name="TodoItem" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" Nullable="false" />
        <Property Name="IsDone" Type="Boolean" Nullable="false" />
      </EntityType>
      <EntityContainer Name="ToDoDBEntities" annotation:LazyLoadingEnabled="true">
        <EntitySet Name="ToDos" EntityType="Self.ToDo" />
      </EntityContainer>
      </Schema>
    </edmx:ConceptualModels>
  • Storage schema definition: This specifies how the storage model is created, that is, how the values are stored in the database:

    <edmx:StorageModels>
      <Schema Namespace="ToDoDBModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
      <EntityType Name="ToDos">
        <Key>
        <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="int" Nullable="false" />
        <Property Name="Todo" Type="nvarchar(max)" Nullable="false" />
        <Property Name="IsDone" Type="bit" Nullable="false" />
      </EntityType>
      <EntityContainer Name="ToDoDBModelStoreContainer">
        <EntitySet Name="ToDos" EntityType="Self.ToDos" Schema="dbo" store:Type="Tables" />
      </EntityContainer>
      </Schema>
    </edmx:StorageModels>
  • Mapping: This specifies the mapping between the conceptual model and the storage model:

    <edmx:Mappings>
      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
      <EntityContainerMapping StorageEntityContainer="ToDoDBModelStoreContainer" CdmEntityContainer="ToDoDBEntities">
        <EntitySetMapping Name="ToDos">
        <EntityTypeMapping TypeName="ToDoDBModel.ToDo">
          <MappingFragment StoreEntitySet="ToDos">
          <ScalarProperty Name="Id" ColumnName="Id" />
          <ScalarProperty Name="TodoItem" ColumnName="Todo" />
          <ScalarProperty Name="IsDone" ColumnName="IsDone" />
          </MappingFragment>
        </EntityTypeMapping>
        </EntitySetMapping>
      </EntityContainerMapping>
      </Mapping>
    </edmx:Mappings>

Tip

We should always prefer to change these values from the Visual Entity Designer. We can modify this XML manually to change it as per our needs, but Visual Entity Designer allows us to perform most of the modifications, and unless we need to make a change that is not supported by entity designer, we should try not to make them manually.

Once the EDM is created, we will get a class generated for each model object present in our conceptual model. We will also get the DBContext class that will let's use these strongly typed models:

Solution Explorer showing the generated DbContext and Model class

The generated DBContext class will look like this:

public partial class ToDoDBEntities : DbContext
{
    public ToDoDBEntities()
        : base("name=ToDoDBEntities")
    {
    }
    
    public virtual DbSet<ToDo> ToDos { get; set; }
}

The generated model class will look like this:

public partial class ToDo
{
    public int Id { get; set; }
    public string TodoItem { get; set; }
    public bool IsDone { get; set; }
}

Now we are ready to write typed queries against the generated conceptual model, and Entity Framework will execute our queries on the database, and return the results in the form of these strongly typed models. Creating new data or updating the existing data is also very easy, because Entity Framework automatically tracks the changes we make in our models, and lets us save the changes to the database. This can simply be done by calling the SaveChanges method on the DBContext class. One important thing to note here is that the read operation can utilize Language-Integrated Query (LINQ) to query the object data model, and Entity Framework will take care of converting it to the appropriate SQL query and retrieve the results.

If our application is a data-centric application, and all we need is to be able to perform CRUD operations using strongly typed objects, this is all that we are going to need. However, one of the great benefits of Entity Framework is being able to modify the conceptual models to better adapt to our domain needs, and then use the mappings to map the domain model to the database tables. We can have relationships between our domain models and still let them persist the data in a given set of tables.

Tip

In the Database First approach, the Entity Model is able to incrementally update the conceptual model if the database schema is updated. We just need to right-click on the visual designer and chose Update Model from Database.

In the later chapters, we will see how to manage multiple models, how we can define relationships between the entities, introduce inheritance hierarchies, customize entities, and much more. This will give you a good foundation to get started with the Entity Framework Database First approach if you haven't used it before, and will refresh your memory if you have.