(Entity FrameWork)Code First to an Existing Database

Pre-Requisites

You will need to have Visual Studio 2010 or Visual Studio 2012 installed to complete this walkthrough.

If you are using Visual Studio 2010, you will also need to have NuGet installed.

You will also need the Entity Framework Power Tools installed. These Power Tools provide some additional Visual Studio tooling to help with Code First development, including the ability to reverse engineer a Code First model from an existing database.

 

1. Create an Existing Database

Typically when you are targeting an existing database it will already be created, but for this walkthrough we need to create a database to access.

The database server that is installed with Visual Studio is different depending on the version of Visual Studio you have installed:

  • If you are using Visual Studio 2010 you‘ll be creating a SQL Express database.
  • If you are using Visual Studio 2012 then you‘ll be creating a LocalDb database.

 

Let‘s go ahead and generate the database.

  • Open Visual Studio
  • View -> Server Explorer
  • Right click on Data Connections -> Add Connection…
  • If you haven’t connected to a database from Server Explorer before you’ll need to select Microsoft SQL Server as the data source
    (Entity FrameWork)Code First to an Existing Database
  • Connect to either LocalDb ((localdb)\v11.0) or SQL Express (.\SQLEXPRESS), depending on which one you have installed, and enter Blogging as the database name
    (Entity FrameWork)Code First to an Existing Database(Entity FrameWork)Code First to an Existing Database
  • Select OK and you will be asked if you want to create a new database, select Yes
    (Entity FrameWork)Code First to an Existing Database
  • The new database will now appear in Server Explorer, right-click on it and select New Query
  • Copy the following SQL into the new query, then right-click on the query and select Execute

  1. CREATE TABLE [dbo].[Blogs] (
  2.     [BlogId] INT IDENTITY (11) NOT NULL,
  3.     [Name] NVARCHAR (200) NULL,
  4.     [Url]  NVARCHAR (200) NULL,
  5.     CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
  6. );
  7.  
  8. CREATE TABLE [dbo].[Posts] (
  9.     [PostId] INT IDENTITY (11) NOT NULL,
  10.     [Title] NVARCHAR (200) NULL,
  11.     [Content] NTEXT NULL,
  12.     [BlogId] INT NOT NULL,
  13.     CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC),
  14.     CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
  15. );

2. Create the Application

To keep things simple we’re going to build a basic console application that uses Code First to perform data access:

  • Open Visual Studio
  • File -> New -> Project…
  • Select Windows from the left menu and Console Application
  • Enter CodeFirstExistingDatabaseSample as the name
  • Select OK

 

3. Reverse Engineer Model

We’re going to make use of the Entity Framework Power Tools to help us generate some initial code to map to the database. These tools are just generating code that you could also type by hand if you prefer.

  • Right-click on the CodeFirstExistingDatabaseSample project in Solution Explorer
  • Select Entity Framework -> Reverse Engineer Code First
    (If you don’t see the Entity Framework option, ensure you have the EF Power Tools installed. You’ll need to restart Visual Studio after installing them)
    (Entity FrameWork)Code First to an Existing Database
  • Enter the same connection details you supplied in the first section, when you created the database
  • The status bar at the bottom of Visual Studio will display the status of the reverse engineering process
    (Entity FrameWork)Code First to an Existing Database

 

Once the reverse engineer process completes a number of items will have been added to the project, let‘s take a look at what‘s been added.

Configuration file

An App.config file has been added to the project, this file contains the connection string to the existing database.


  1. <connectionStrings>
  2.   <add name="BloggingContext" 
  3.        connectionString="Data Source=(localdb)\v11.0;Initial Catalog=Blogging;Integrated Security=True;MultipleActiveResultSets=True"
  4.        providerName="System.Data.SqlClient" />
  5. </connectionStrings>

You’ll notice some other settings in the configuration file too, these are default EF settings that tell Code First where to create databases. Since we are mapping to an existing database these setting will be ignored in our application.

Derived Context

A BloggingContext class has been created in the Models folder. The context represents a session with the database, allowing us to query and save data.

The context exposes a DbSet<TEntity> for each type in our model.


  1. public DbSet<Blog> Blogs { get; set; }
  2. public DbSet<Post> Posts { get; set; }

You’ll also notice that the default constructor calls a base constructor using the ‘name=’ syntax. This tells Code First that the connection string to use for this context should be loaded from the configuration file.


  1. public BloggingContext()
  2.     : base("Name=BloggingContext")
  3. {
  4. }

You should always use the ‘name=’ syntax when you are using a connection string in the config file. This ensures that if the connection string is not present then Entity Framework will throw rather than creating a new database by convention.

Model classes

In the Models folder you’ll also find a Blog and Post class. These are the domain classes that make up our model.


  1. public class Blog
  2. {
  3.     public Blog()
  4.     {
  5.         this.Posts = new List<Post>();
  6.     }
  7.  
  8.     public int BlogId { get; set; }
  9.     public string Name { get; set; }
  10.     public string Url { get; set; }
  11.     public virtual ICollection<Post> Posts { get; set; }
  12. }

Configuration classes

In the Models\Mapping folder you’ll find a set of configuration classes that use the fluent API to configure how the classes map to the database.


  1. public class BlogMap : EntityTypeConfiguration<Blog>
  2. {
  3.     public BlogMap()
  4.     {
  5.         // Primary Key
  6.         this.HasKey(t => t.BlogId);
  7.  
  8.         // Properties
  9.         this.Property(t => t.Name)
  10.             .HasMaxLength(200);
  11.  
  12.         this.Property(t => t.Url)
  13.             .HasMaxLength(200);
  14.  
  15.         // Table & Column Mappings
  16.         this.ToTable("Blogs");
  17.         this.Property(t => t.BlogId).HasColumnName("BlogId");
  18.         this.Property(t => t.Name).HasColumnName("Name");
  19.         this.Property(t => t.Url).HasColumnName("Url");
  20.     }
  21. }

Many developers would rather use Data Annotations than the fluent API to perform configuration. Currently the EF Power Tools only generates fluent API code but there are plans to enable a choice between fluent API and Data Annotations in the future.

The mapping is also redundant in some cases. For example, BlogId is configured as they key even though Code First would detect this by convention. Similarly, the properties are all explicitly mapped to columns even though the column and property names match up and would be detected by convention. You may choose to delete the generated configuration in cases where it is not required.

 

4. Reading & Writing Data

Now that we have a model it’s time to use it to access some data. We’re going to start using the classes that were added to the Models folder, so we need to add a using at the top of Program.cs.


  1. using CodeFirstExistingDatabaseSample.Models;

Implement the Main method in Program.cs as shown below. This code creates a new instance of our context and then uses it to insert a new Blog. Then it uses a LINQ query to retrieve all Blogs from the database ordered alphabetically by Title.


  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         using (var db = new BloggingContext())
  6.         {
  7.             // Create and save a new Blog
  8.             Console.Write("Enter a name for a new Blog: ");
  9.             var name = Console.ReadLine();
  10.  
  11.             var blog = new Blog { Name = name };
  12.             db.Blogs.Add(blog);
  13.             db.SaveChanges();
  14.  
  15.             // Display all Blogs from the database
  16.             var query = from b in db.Blogs
  17.                         orderby b.Name
  18.                         select b;
  19.  
  20.             Console.WriteLine("All blogs in the database:");
  21.             foreach (var item in query)
  22.             {
  23.                 Console.WriteLine(item.Name);
  24.             }
  25.  
  26.             Console.WriteLine("Press any key to exit...");
  27.             Console.ReadKey();
  28.         }
  29.     }
  30. }

You can now run the application and test it out.

Enter a name for a new Blog: ADO.NET Blog
All blogs in the database:
ADO.NET Blog
Press any key to exit...

 

What if My Database Changes?

The EF Power Tools are designed to generate a starting point set of classes that you can then tweak and modify. If your database schema changes you can either manually edit the classes or perform another reverse engineer to overwrite the classes.

The code that gets generated by the reverse engineer process can be customized by modifying the templates that are used to generate code. You can find an example of this in the Customizing ‘Reverse Engineer Code First’ in the EF Power Tools post.

 

Summary

In this walkthrough we looked at Code First development using an existing database. We used the Entity Framework Power Tools to reverse engineer a set of classes that mapped to the database and could be used to store and retrieve data.

 

 原文地址: http://msdn.microsoft.com/en-us/data/jj200620.aspx

(Entity FrameWork)Code First to an Existing Database

上一篇:深入理解计算机系统--信号


下一篇:linux下tar用法