Entity Framework 4.1: Basics (1)

  As its name suggest, with code-first, you start with the code.  You can create the corresponding database directly from the code, but you could also be working from an existing DB.  The advantage of code-first is that your entity-classes don’t have any EF artefacts on them:  they don’t derive from a specific class and they do not have funky attributes on them.  Well…  for the attributes, as we’ll see, that’s optional!

  Let’s start with a simple entity model:  Order and OrderDetail.  We start by modelling it as classes:

public class Order
{
    public int OrderID { get; set; }
    public string OrderTitle { get; set; }
    public string CustomerName { get; set; }
    public DateTime TransactionDate { get; set; }

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

public class OrderDetail
{
    public int OrderDetailID { get; set; }
    public int OrderID { get; set; }
    public decimal Cost { get; set; }
    public string ItemName { get; set; }

    public Order Order { get; set; }
}

  

  Note the following about those classes:

  • They do not derive from any EF classes
  • They do not use EF attributes
  • An Order contains a list of OrderDetail and an OrderDetail contains a reference to its Order
  • Each property is either
    • A simple CLR Type (e.g. string, int, etc.)
    • An entity-type (e.g. Order)
    • A list of entity type (e.g. List<OrderDetail>)

In order to map those class into a DB, we need a container, a database-context:

public class MyDomainContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }

    static MyDomainContext()
    {
        Database.SetInitializer<MyDomainContext>(new DropCreateDatabaseIfModelChanges<MyDomainContext>());
    }
}

This class is EF-aware It doesn’t have to sit in the same assembly than your model classes though.

At least a context must satisfy the following:

  • It derives from System.Data.Entity.DbContext
  • It has a property for each entity set we want to expose
  • Each property is of type System.Data.Entity.DbSet<T> where T is the type of the entity
  • Each property is read / write (get / set)

With that in place在这里, the DbContext base class uses reflection to pick-up the entity-sets and a bunch of convention to infer the underlying database model it should map to.

The conventions take decisions such as for the entity of type Order, the property OrderID must be its primary key.  Other convention will infer the column-name (by default the property name), the column type (e.g. a string maps to nvarchar(128) and should be nvarchar(MAX) in the final version), if a column is nullable (by default, all column but primary and foreign keys are nullable), etc.  .  We’ll see that there are ways to override those conventions.

We’ve added a static constructor here.  The instruction in the static constructor sets a standard for the entire app-domain:  when a database context is initialized, check if the schema in the database is conform to the model and if not drop the DB and recreate it.  The way this is done is that EF creates a table dbo.EdmMetadata and persist a hash of the model schema in it.

If the database doesn’t exist, EF will create it.  Which database?  By default, it creates a DB with the name of your context on the local machine.  You can override that in many ways.  The simplest is to add a connection string in your configuration file with the name of the context (in my case, "MyDomainContext").  Another way is to implement a constructor and call the non-default base-class constructor in it.

In the next blob entry, I’ll show how to override the conventions.

原文地址:https://www.cnblogs.com/jackyfei/p/ef_Basic.html