Entity Framework Code 5 series First database migration

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

We know that both "Database First" or "Model First" when the model changes can be updated through the Visual Studio design view, then the Code First how to update the existing model? Today, we simply introduce the Entity Framework data transfer function.

Entity Framework configuration

Before the start of today's topic first look at the Entity Framework configuration, because there are a lot of friends because of the configuration file "Migrations" command execution problems caused by failure.

After the establishment of an application we can make right click "Nuget Packages Manage" on the project EF package is installed or directly in the "Package Manager Console" input "Install-Package EntityFramework" command to Entity Framework package is installed. This process not only download and introducing the relevant program EF frame set of configuration and application package program configuration. Here are the two configuration file:

The packages.config file:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="5.0.0" targetFramework="net45" />
</packages>

The App.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Packages.config content is relatively simple, the first is EF's own version, and then in the installation process according to the current application of.NET Framework version equipped with "targetFramework", because the corresponding to different.NET Framework version of the EF assemblies, which will automatically recognize and configured during setup.

App.config automatically add a "entityFramework" configuration section, in the EF package is installed automatically during the current configuration of the "defaultConnectionFactory", "defaultConnectionFactory" is a connection configuration EF default, not only in the connection string effective configuration. In the last article we mentioned that if not for the connection string configuration EF will automatically recognize and create a database to ".\SQLEXPRESS" or "LocalDb", is in fact the recognition can be seen here, on my machine without the ".\SQLEXPRESS" will automatically use the "LocalDb", the default connection to"LocalDbConnectionFactory".

In this case we need will be connected to the ".\SQL2008", Established in two ways: one is the connection of direct allocation"defaultConnectionFactory", The default generated "System.Data.Entity.Infrastructure.LocalDbConnectionFactory" into"System.Data.Entity.Infrastructure.SqlConnectionFactory", We then write in the connection string parameters (note the default generated database named "project name database context name.").

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="Data Source=.\SQL2008; UID=sa;PWD=123; MultipleActiveResultSets=True" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Another is by the traditional "connectionStrings" configuration, as long as the allocation of the connection string "defaultConnectionFactory" will no longer work, EF will automatically use the connection. In the next example we will use this way.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="CodeFirstDb" connectionString="Data Source=.\SQL2008;Database=CodeFirstDb;UID=sa;PWD=123;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"></add>
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Code First database migration

Let us now based in an article on the Entity Framework 5 series EF Overview "Code First" example to add a "Employee" attribute to the Order, and then run, if no unexpected events occur, you will see the following exception:

We can see from the abnormal information, EF has detected model changes, suggested that we use "Code First Migrations" update the model. The fact that the EF is relying on the mentioned in the previous article "dbo.__MigrationHistory" table to estimate our model, because this table is stored in our model structure (in the Model column), if the applications you run SQL Server EF to perform tracking will find the following SQL model modification judgment:

SELECT Count(*) FROM sys.databases WHERE [name]=N'CodeFirstDb'
go
SELECT TABLE_SCHEMA SchemaName, TABLE_NAME Name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'
go
SELECT Count(*) FROM sys.databases WHERE [name]=N'CodeFirstDb'
go
SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[__MigrationHistory] AS [Extent1]
)  AS [GroupBy1]
go
SELECT TOP (1) 
[Project1].[C1] AS [C1], 
[Project1].[MigrationId] AS [MigrationId], 
[Project1].[Model] AS [Model]
FROM ( SELECT 
    [Extent1].[MigrationId] AS [MigrationId], 
    [Extent1].[Model] AS [Model], 
    1 AS [C1]
    FROM [dbo].[__MigrationHistory] AS [Extent1]
)  AS [Project1]
ORDER BY [Project1].[MigrationId] DESC
go

 

Before the start of the Code First database migration, We first to write on a section of the OrderContext class to modify and add a default constructor, Because the default constructor Code First Migrations will use the database context for data transfer operation (although there is no default constructor all data operations can be carried out as normal, But for the data transfer is a must), So we need to add a default constructor, And must pass in our database connection name the constructor (if the first database using the above we said connection configuration mode you can not transfer the parameters), Otherwise it will update the application to the EF default database. Here are our OrderContext:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;


namespace CodeFirst
{
    public class OrderContext:DbContext
    {
        public OrderContext()
            : base("CodeFirstDb")
        {
        }

        public DbSet<Order> Orders
        {
            get;
            set;
        }

        public DbSet<OrderDetail> OrderDetails
        {
            get;
            set;
        }
    }
}

Below we will with "Code First Magrations" for model updating.

Implementation of Studio in Visual: Tools-> Library Package Manager-> Package Manager Console to open the package management command line:

Enter "Enable-Migrations -StartUpProjectName CodeFirst" and press enter at the command line ("CodeFirst" is your project name, If the "Package Manager Console" to choose the default project can not set the "-StartUpProjectName" parameter; if repeated execution of this command can add the -Force parameter):

 

Note: if you receive the following error in operation "Enable-Migrations -StartUpProjectName CodeFirst" command in the process, please try the following given:

Enable-Migrations : The term 'Enable-Migrations' is not recognized as the name of a cmdlet, function, script file, or operable

program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

1 in the Package Manager Console command: Import-Module F:\[7]CSharp\EntityFramework\CodeFirst\packages\EntityFramework.5.0.0\tools\EntityFramework.PS3.psd1 (behind the path according to the actual position of your EF package modification, This is because there is no import the appropriate command caused)

2 the implementation of "Install-Package EntityFramework -IncludePrerelease" command to install the latest version of EF (also designated specific version of the -Version parameter).

Update on Nuget 3, the update step see Installing NuGet.

4 in addition, during command execution errors can prompt resolution in accordance with the error.

If there are no mistakes in your project will automatically generate a name for the "Migrations" folder, which contains two files: Configuration.cs and 201308211510117_InitialCreate.cs (201308211510117 time stamp).

Configuration.cs: is the transport configuration code, usually we don't need to modify the.

namespace CodeFirst.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<CodeFirst.OrderContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

        protected override void Seed(CodeFirst.OrderContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
    }
}

201308211510117_InitialCreate.cs: in the form of code record table structure definition of local database.

namespace CodeFirst.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class InitialCreate : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Orders",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Customer = c.String(),
                        OrderDate = c.DateTime(nullable: false),
                    })
                .PrimaryKey(t => t.Id);
            
            CreateTable(
                "dbo.OrderDetails",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Product = c.String(),
                        UnitPrice = c.String(),
                        OrderId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Orders", t => t.OrderId, cascadeDelete: true)
                .Index(t => t.OrderId);
            
        }
        
        public override void Down()
        {
            DropIndex("dbo.OrderDetails", new[] { "OrderId" });
            DropForeignKey("dbo.OrderDetails", "OrderId", "dbo.Orders");
            DropTable("dbo.OrderDetails");
            DropTable("dbo.Orders");
        }
    }
}

 

Now in the "Package Manager Console" in "Add-Migration AddEmployee" command, This command will automatically comparison table structure model and in the current database, Then the implementation of "AddEmployee" to add a "Employee" column, At this point in the "Migrations" folder will generate a "201308240757094_AddEmployee.cs" class (201308240757094 is the time stamp):

201308240757094_AddEmployee.cs are as follows:

namespace CodeFirst.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class AddEmployee : DbMigration
    {
        public override void Up()
        {
            AddColumn("dbo.Orders", "Employee", c => c.String());
        }
        
        public override void Down()
        {
            DropColumn("dbo.Orders", "Employee");
        }
    }
}

From this class we can see that in fact is to "Order" to add the "Employee" column, of course we can manually modify the class.

Next, in the "Package Manager Console" in "Update-Database -StartUpProjectName CodeFirst - Verbose" command (add the -Verbose parameter can see the update script), database update:

The database view, found that the "Order" table has a column:

OK, Today our content first here, about how the database according to the generated code classes and the more we in the behind of the article to explore together.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Christina at November 13, 2013 - 2:49 PM