EF 4.1 Code First Walkthrough(EF 4.1代码优先演练)

来源:互联网 发布:逛淘宝费多少流量 编辑:程序博客网 时间:2024/06/06 07:24

Mappingto an Existing Database

This walkthrough is going to demonstrateCode First generating the database schema but the same principals apply tomapping to an existing database, with the exception of ‘7. Setting anInitialization Strategy’ which does not apply to existingdatabases. If Code First is pointed at an existing database that it did notcreate then it will just attempt to use the specified configuration to accessthe database. The easiest way to point Code First to an existing database is toadd a App/Web.config connection string with the same name as your derivedDbContext, for example;

<connectionStrings>

 <add

   name="MyProductContext"

   providerName="System.Data.SqlClient"

   connectionString="Server=./SQLEXPRESS;Database=Products;Trusted_Connection=true;"/>

</connectionStrings>

 

1. Install EF 4.1

If you haven’t already done so then youneed to install Entity Framework 4.1

 

2. Create the Application

To keep things simple we’re going tobuild up a basic console application that uses the Code First to perform dataaccess:

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

 

3. Create the Model

Let’s define a very simple model usingclasses. I’m just defining them in the Program.cs file but in a real worldapplication you would split your classes out into separate files andpotentially a separate project.

Below the Program class definition inProgram.cs I am defining the following two classes:

public class Category

{

   public string CategoryId { get; set; }

   public string Name { get; set; }

 

   public virtual ICollection<Product> Products { get; set; }

}

 

public class Product

{

   public int ProductId { get; set; }

   public string Name { get; set; }

   public string CategoryId { get; set; }

 

   public virtual Category Category { get; set; }

}

 

4. Create a Context

The simplest way to start using theclasses for data access is to define a context that derives fromSystem.Data.Entity.DbContext and exposes a typed DbSet<TEntity> for eachclass in my model.

We’re now starting to use types from EF4.1 so we need to add a reference to the EntityFramework assembly:

  • Project -> Add Reference…
  • Select the “.NET” tab
  • Select “EntityFramework” from the list
  • Click “OK”

You’ll also need a reference to theexisting Entity Framework assembly:

  • Project -> Add Reference…
  • Select the “.NET” tab
  • Select “System.Data.Entity” from the list
  • Click “OK”

Add a using statement forSystem.Data.Entity at the top of Program.cs

using System.Data.Entity;

Add a derived context below the existingclasses that we’ve defined

public class ProductContext : DbContext

{

   public DbSet<Category> Categories { get; set; }

   public DbSet<Product> Products { get; set; }

}

That is all the code we need to write tostart storing and retrieving data. Obviously there is quite a bit going onbehind the scenes and we’ll take a look at that in a moment but first let’s seeit in action.

5. Reading & Writing Data

I’m padding out the Main method in myprogram class as follows:

class Program

{

   static void Main(string[] args)

   {

       using (var db = new ProductContext())

       {

            // Add a food category

           var food = new Category { CategoryId = "FOOD", Name = "Foods" };

            db.Categories.Add(food);

            int recordsAffected = db.SaveChanges();

 

            Console.WriteLine(

                "Saved {0} entities to the database,press any key to exit.",

                recordsAffected);

 

            Console.ReadKey();

       }

   }

}

You can now run the application and seethat the new category is inserted.

Where’sMy Data?

DbContext by convention created adatabase for you on localhost/SQLEXPRESS. The database is named after the fullyqualified name of your derived context, in our case that is“CodeFirstSample.ProductContext”. We’ll look at ways to change this later inthe walkthrough.

ModelDiscovery

DbContext worked out what classes toinclude in the model by looking at the DbSet properties that we defined. Itthen uses the default Code First conventions to find primary keys, foreign keysetc.

 

6. Reading & Writing More Data

Let’s pad out the program we just wroteto show a bit more functionality. We are going to make use of the Find methodon DbSet that will locate an entity based on primary key. If no match is foundthen Find will return null. We’re also making use of LINQ to query for allproducts in the Food category ordered alphabetically by name. Querying uses theexiting LINQ to Entities provider so it supports the same queries that arepossible with ObjectSet/ObjectQuery in EF4.

I’m replacing the Main we wrote abovewith the following:

class Program

{

   static void Main(string[] args)

   {

       using (var db = new ProductContext())

       {

            // Use Find to locate the Food category

           var food = db.Categories.Find("FOOD");

           if (food == null)

            {

                food = new Category { CategoryId = "FOOD", Name = "Foods" };

                db.Categories.Add(food);

            }

 

            // Create a new Food product

           Console.Write("Please enter a name for a new food:");

            var productName = Console.ReadLine();

 

            var product = new Product { Name = productName, Category = food };

            db.Products.Add(product);

 

            int recordsAffected = db.SaveChanges();

 

            Console.WriteLine(

                "Saved {0} entities to thedatabase.",

                recordsAffected);

 

            // Query for all Food products using LINQ

           var allFoods = from p in db.Products

                            where p.CategoryId == "FOOD"

                            orderby p.Name

                            select p;

 

            Console.WriteLine("All foods in database:");

            foreach (var item in allFoods)

            {

                Console.WriteLine(" - {0}", item.Name);

            }

 

            Console.WriteLine("Press any key to exit.");

            Console.ReadKey();

       }

   }

}

 

7. Setting an Initialization Strategy

In the next section we are going tostart changing our model which in turn means the database schema needs tochange as well. Currently there is no ‘out of the box’ solution to evolve yourexisting schema in place. Database evolution is something we are currentlyworking on and a sample of the direction we are heading is provided in arecent design blog post.

There is however the opportunity to runsome custom logic to initialize the database the first time a context is usedin an AppDomain. This is handy if you want to insert seed data for test runsbut it’s also useful to re-create the database if the model has changed. In EF4.1 we include a couple of strategies you can plug in but you can also writecustom ones.

For the walkthrough we just want to dropand re-create the database whenever the model has changed, so at the top of theMain method in my Program class I’ve added the following code

Database.SetInitializer<ProductContext>(
   
new DropCreateDatabaseIfModelChanges<ProductContext>());

 

8. Data Annotations 数据描述

So far we’ve just let EF discover themodel using its default conventions but there are going to be times when ourclasses don’t follow the conventions and we need to be able to perform furtherconfiguration. There are two options for this; we’ll look at Data Annotationsin this section and then the fluent API in the next section.

Let’s add a supplier class to our model:

public class Supplier

{

   public string SupplierCode { get; set; }

   public string Name { get; set; }

}

And we also need to add a set to ourderived context

public class ProductContext : DbContext

{

   public ProductContext()

   { }

 

   public DbSet<Category> Categories { get; set; }

   public DbSet<Product> Products { get; set; }

   publicDbSet<Supplier> Suppliers { get; set; }

}

Now if we ran our application we’d getan InvalidOperationException saying “EntityType'Supplier' has no key defined. Define the key for this EntityType.” because EF hasno way of knowing that SupplierCode should be the primary key for Supplier.

We’re going to use Data Annotations nowso we need to add a reference:

  • Project -> Add Reference…
  • Select the “.NET” tab
  • Select “System.ComponentModel.DataAnnotations” from the list
  • Click “OK

Add a using statement at the top ofProgram.cs:

using System.ComponentModel.DataAnnotations;

Now we can annotate the SupplierCodeproperty to identify that it is the primary key:

public class Supplier

{

   [Key]

   public string SupplierCode { get; set; }

   public string Name { get; set; }

}

The full list of annotations supportedin EF 4.1 is;

  • KeyAttribute
  • StringLengthAttribute
  • MaxLengthAttribute
  • ConcurrencyCheckAttribute
  • RequiredAttribute
  • TimestampAttribute
  • ComplexTypeAttribute
  • ColumnAttribute 
    Placed on a property to specify the column name, ordinal & data type
  • TableAttribute 
    Placed on a class to specify the table name and schema
  • InversePropertyAttribute 
    Placed on a navigation property to specify the property that represents the other end of a relationship
  • ForeignKeyAttribute 
    Placed on a navigation property to specify the property that represents the foreign key of the relationship
  • DatabaseGeneratedAttribute 
    Placed on a property to specify how the database generates a value for the property (Identity, Computed or None)
  • NotMappedAttribute 
    Placed on a property or class to exclude it from the database

 

9. Fluent API

In the previous section we looked atusing Data Annotations to supplement or override what was detected byconventions. The other way to further configure the model is via the Code Firstfluent API. The fluent API is considered a more advanced feature and we wouldrecommend using Data Annotations unless your requirements require you to usethe fluent API.

To access the fluent API we override theOnModelCreating method in DbContext, in the following code we are using thefluent API to configure the Name property on Supplier to be required.

public class ProductContext : DbContext

{

   public ProductContext()

   { }

 

   public DbSet<Category> Categories { get; set; }

   public DbSet<Product> Products { get; set; }

   public DbSet<Supplier> Suppliers { get; set; }

 

   protectedoverride void OnModelCreating(DbModelBuilder modelBuilder)

   {

       modelBuilder.Entity<Supplier>()

           .Property(s => s.Name)

           .IsRequired();

   }

}

 

Summary

In this walkthrough we looked at CodeFirst development using the EF 4.1. We looked at defining and configuring amodel, storing and retrieving data, configuring the database connection,updating the database schema as our model evolved and validating data before itis written to the database.

Support

This is a fully supported release. The ADO.NET Entity Framework Forum can be used forquestions relating to this release. Further information about getting technicalsupport can be found at the Microsoft Support website.

Rowan Miller 
Program Manager
 
ADO.NET Entity Framework

 

原创粉丝点击