来源:http://msdn.microsoft.com/zh-cn/data/jj193542

本视频和分步演练介绍通过 Code First 开发建立新数据库。这个方案包括建立不存在的数据库(Code First 创建)或者空数据库(Code First 向它添加新表)。借助 Code First,可以使用 C# 或 VB.Net 类定义模型。可以选择使用类的特性和属性执行其他配置,也可以使用 Fluent API 执行其他配置。

 
 

必备条件

要完成本演练,需要安装 Visual Studio 2010 或 Visual Studio 2012。

如果使用的是 Visual Studio 2010,还需要安装 NuGet

1.创建应用程序

简单起见,我们将构建一个使用 Code First 执行数据访问的基本控制台应用程序。

  • 打开 Visual Studio
  • “文件”->“新建”->“项目…”
  • 从左侧菜单中选择“Windows”和“控制台应用程序”
  • 输入 CodeFirstNewDatabaseSample 作为名称
  • 选择“确定”

2.创建模型

我们使用类来定义一个非常简单的模型。在 Program.cs 文件中进行定义,但是实际应用程序中,可能会将类分为若干个单独的文件,可能作为单独的项目。

在 Program.cs 中的程序类定义下,添加以下两个类。

public class Blog 

    public int BlogId { get; set; } 
    public string Name { get; set; } 
 
    public virtual List<Post> Posts { get; set; } 

 
public class Post 

    public int PostId { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 
 
    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; } 
}

可以看到,我们将虚拟化两个导航属性(Blog.Posts 和 Post.Blog)。这将启用实体框架的延迟加载功能。延迟加载意味着,尝试访问这些属性的内容时,将自动从数据库加载。

3.创建上下文

现在,可以定义派生上下文,用于表示数据库的一个会话,以便我们查询和保存数据。我们定义一个派生自 System.Data.Entity.DbContext 的上下文,并为模型中的每个类公开一个类型化 DbSet<TEntity>。

现在,开始使用来自实体框架的类型。因此,我们需要添加 EntityFramework NuGet 程序包。

  • “项目”–>“管理 NuGet 程序包…”
    注意:如果没有“管理 NuGet 程序包…”选项,则应安装 最新版本的 NuGet
  • 选择“联机”选项卡
  • 选择“EntityFramework”程序包
  • 单击“安装”

在 Program.cs 顶部,为 System.Data.Entity 添加一个 using 语句。

using System.Data.Entity;

在 Program.cs 中的 Post 类下,添加以下派生上下文。

public class BloggingContext : DbContext 

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

下面是 Program.cs 现在应包含内容的完整列表。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Data.Entity; 
 
namespace CodeFirstNewDatabaseSample 

    class Program 
    { 
        static void Main(string[] args) 
        { 
        } 
    } 
 
    public class Blog 
    { 
        public int BlogId { get; set; } 
        public string Name { get; set; } 
 
        public virtual List<Post> Posts { get; set; } 
    } 
 
    public class Post 
    { 
        public int PostId { get; set; } 
        public string Title { get; set; } 
        public string Content { get; set; } 
 
        public int BlogId { get; set; } 
        public virtual Blog Blog { get; set; } 
    } 
 
    public class BloggingContext : DbContext 
    { 
        public DbSet<Blog> Blogs { get; set; } 
        public DbSet<Post> Posts { get; set; } 
    } 
}

这是我们开始存储和检索数据所需的全部代码。显然,后台发生了许多事情。稍后,我们将进行了解。但是,首先让我们看看它是如何运行的。

4.读写数据

实现 program.cs 中的 Main 方法,如下所示。这些代码为上下文创建一个新实例,然后使用该实例插入新博客。之后,它使用 LINQ 查询检索数据库中的所有博客(按标题的字母顺序进行排序)。

class Program 

    static void Main(string[] args) 
    { 
        using (var db = new BloggingContext()) 
        { 
            // Create and save a new Blog 
            Console.Write("Enter a name for a new Blog: "); 
            var name = Console.ReadLine(); 
 
            var blog = new Blog { Name = name }; 
            db.Blogs.Add(blog); 
            db.SaveChanges(); 
 
            // Display all Blogs from the database 
            var query = from b in db.Blogs 
                        orderby b.Name 
                        select b; 
 
            Console.WriteLine("All blogs in the database:"); 
            foreach (var item in query) 
            { 
                Console.WriteLine(item.Name); 
            } 
 
            Console.WriteLine("Press any key to exit..."); 
            Console.ReadKey(); 
        } 
    } 
}

现在,可以运行应用程序,对其进行测试。

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

我的数据在哪里?

按照约定,DbContext 已经创建了一个数据库。

  • 如果本地 SQL Express 实例可用(默认情况下随 Visual Studio 2010 安装),则 Code First 已对该实例创建了数据库
  • 如果 SQL Express 不可用,则 Code First 将尝试使用 LocalDb(默认情况下随 Visual Studio 2012 安装)
  • 数据库以派生上下文的完全限定名命名,在我们的示例中,名称为 CodeFirstNewDatabaseSample.BloggingContext

这些仅仅是默认约定,除此之外,还有多种方式可更改 Code First 所用的数据库。有关更多信息,请参见DbContext 如何发现模型和数据库连接 主题。

可以在 Visual Studio 中使用服务器资源管理器连接至此数据库

  • “视图”->“服务器资源管理器”
  • 右键单击“数据连接”并选择“添加连接…”
  • 如果尚未从服务器资源管理器连接至数据库,则需要选择 Microsoft SQL Server 作为数据源
  • 连接至 LocalDb ((localdb)\v11.0) 或 SQL Express (.\SQLEXPRESS),具体取决于安装情况

现在,可以检查 Code First 已经创建的架构。

DbContext 通过查看我们定义的 DbSet 属性,了解模型包含哪些类。随后,它使用 Code First 约定的默认集来确定表和列的名称,确定数据类型,查找主键等。本演练稍后将介绍如何重写这些约定。

5.处理模型更改

现在更改模型,当我们进行更改时,还需要更新数据库架构。为此,我们使用一个称为“Code First 迁移”(或简称“迁移”)的功能。

“迁移”是一组有序的步骤,描述如何升级(和降级)数据库架构。这些步骤(称为“迁移”)中的每个步骤均包含一些代码,用于描述要应用的更改。

第一步是为 BloggingContext 启用 Code First 迁移。

  • “工具”->“库程序包管理器”->“程序包管理器控制台”
  • 在程序包管理器控制台中运行 Enable-Migrations 命令
  • 一个新的 Migrations 文件夹已添加至项目中,它包含两个文件:
    • Configuration.cs — 此文件包含“迁移”将用来迁移 BloggingContext 的设置。在本演练中不需要进行任何更改,但是,在此处可以指定种子数据、为其他数据库注册提供程序、更改生成迁移的命名空间等。
    • <时间戳>_InitialCreate.cs — 这是第一个迁移,它表示已经应用于数据库的更改。应用更改的目的是将其从空数据库迁移至包含博客和文章表的数据库。尽管我们让 Code First 自动创建这些表,现在我们选择“迁移”(已转化为一次“迁移”)。Code First 还在本地数据库中记录:该“迁移”已经应用。文件名中的时间戳用于排序。

    现在,更改模型,向 Blog 类添加一个 Url 属性:

public class Blog 

    public int BlogId { get; set; } 
    public string Name { get; set; } 
    public string Url { get; set; } 
 
    public virtual List<Post> Posts { get; set; } 
}
  • 在程序包管理器控制台中运行 Add-Migration AddUrl 命令。

    Add-Migration 命令检查自上次迁移后是否有更改,并使用所有更改搭建新迁移。我们可以为迁移指定名称;在本例中,将此迁移称为“AddUrl”。

    搭建的代码表明:我们需要向 dbo.Blogs 表添加可容纳字符串数据的 Url 列。如果需要,可以对搭建的代码进行编辑,但是,在本例中,没有这个必要。

namespace CodeFirstNewDatabaseSample.Migrations 

    using System; 
    using System.Data.Entity.Migrations; 
     
    public partial class AddUrl : DbMigration 
    { 
        public override void Up() 
        { 
            AddColumn("dbo.Blogs", "Url", c => c.String()); 
        } 
         
        public override void Down() 
        { 
            DropColumn("dbo.Blogs", "Url"); 
        } 
    } 
}
  • 在程序包管理器控制台中运行 Update-Database 命令。此命令将所有挂起的迁移应用于数据库。InitialCreate 迁移已经应用,因此,这些迁移将仅应用新的 AddUrl 迁移。

    提示:在调用 Update-Database 命令查看对数据库执行的 SQL 时,可以使用 –Verbose 开关。

新的 Url 列已添加至数据库中的 Blogs 表:

6.数据注释

到目前为止,EF 发现了使用其默认约定的模型。但是,有时类不遵从约定,我们需要能够执行进一步配置。对此有两种方法;本节将介绍数据注释,下一节将介绍 Fluent API。

  • 向模型添加用户类
public class User 

    public string Username { get; set; } 
    public string DisplayName { get; set; } 
}
  • 我们还需要向派生上下文添加一个集
public class BloggingContext : DbContext 

    public DbSet<Blog> Blogs { get; set; } 
    public DbSet<Post> Posts { get; set; } 
    public DbSet<User> Users { get; set; } 
}
  • 如果尝试添加迁移,会收到错误消息“EntityType‘User’未定义键。请为该 EntityType 定义键。”这是因为 EF 无法知道 Username 应为用户的主键。
  • 我们将使用数据注释,因此需要在 Program.cs 的顶部添加一个 using 语句
using System.ComponentModel.DataAnnotations;
  • 现在,注释 Username 属性,将它标识为主键
public class User 

    [Key] 
    public string Username { get; set; } 
    public string DisplayName { get; set; } 
}
  • 使用 Add-Migration AddUser 命令搭建一个迁移,将这些更改应用于数据库
  • 运行 Update-Database 命令,将新迁移应用于数据库

现在,新表已添加至数据库:

EF 支持的完整注释列表为:

7.Fluent API

上一节介绍了如何使用数据注释来补充或重写按约定检测的内容。另一种模型配置方法是通过 Code First Fluent API。

大多数模型配置都可使用简单数据注释进行。Fluent API 是一种更高级的方法,除某些数据注释不可能支持的更高级配置外,可以指定包含数据注释所有功能的模型配置。数据注释和 Fluent API 可一起使用。

要访问 Fluent API,需要在 DbContext 中重写 OnModelCreating 方法。假设我们需要重命名 User.DisplayName 存储至 display_name 的列。

  • 使用以下代码重写 BloggingContext 的 OnModelCreating 方法
public class BloggingContext : DbContext 

    public DbSet<Blog> Blogs { get; set; } 
    public DbSet<Post> Posts { get; set; } 
    public DbSet<User> Users { get; set; } 
 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
        modelBuilder.Entity<User>() 
            .Property(u => u.DisplayName) 
            .HasColumnName("display_name"); 
    } 
}
  • 使用 Add-Migration ChangeDisplayName 命令搭建迁移,将这些更改应用于数据库。
  • 运行 Update-Database 命令,将新迁移应用于数据库。

DisplayName 列现在重命名为 display_name:

摘要

本演练介绍了如何使用新数据库进行 Code First 开发。我们用类定义一个模型,然后使用该模型创建一个数据库,然后存储和检索数据。数据库创建之后,我们使用 Code First 迁移将架构更改为我们发展后的模型。此外还介绍了如何使用数据注释和 Fluent API 来配置模型。

EntityFrame CodeFirst 自动生成表的更多相关文章

  1. 基于PHP和mysql的自动生成表单

    开发背景:公司要求管理系统能够由管理员在前台页面管理系统表单,能够对表单进行增删改查基本操作,表单的各个字段都可以被修改.删除,可以添加新的字段,并且不影响系统正常运行,前台表单展示要由系统自动处理, ...

  2. hibernate.hbm2ddl.auto=update不能自动生成表结构

    在写上篇文章<spring整合springmvc和hibernate>的时候,曾遇到一个问题 INFO: Server startup in 8102 ms Hibernate: inse ...

  3. java自动生成表单简单实例

    数据库表设置 tb_form(form表单) 字段 类型 约束 说明 Id Int 主键 主键 Formid Varchar2(20) 唯一 Form表单id的值 Action Varchar2(20 ...

  4. hibernate如何配置自动生成表

    hibernate自动生成表有两种方法: 1.直接写代码,通过方法来创建数据库表. 2.通过 hibernate.cfg.xml配置标签来创建数据表. 下面依次实现: 1.直接写代码,通过方法来创建数 ...

  5. 利用powerDesigner15.1连接oracle数据库并自动生成表结构

    利用powerDesigner15.1连接oracle数据库并自动生成表结构 参考:http://blog.csdn.net/qq_24531461/article/details/76713802 ...

  6. 用Django自动生成表遇到问题

    因为以前在数据库中已经生成过Django 叫App01下的表,所以无法生成,在数据库中执行这个命令 DELETE FROM django_migrations WHERE app='App01';然后 ...

  7. EntityFramework系列:SQLite.CodeFirst自动生成数据库

    http://www.cnblogs.com/easygame/p/4447457.html 在Code First模式下使用SQLite一直存在不能自动生成数据库的问题,使用SQL Server C ...

  8. Hibernate使用自定义脚本替换注解或者xml文件中的自动生成表结构

    本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50534361 我们都清楚,可以使用hibernate的metada ...

  9. yii2自动生成表单

    视图中: 1.要use的两个文件类 use yii\helpers\Html;   use yii\widgets\ActiveForm; 2.生成表单,以添加商品为例说明.注意红线区域:上传文件需要 ...

随机推荐

  1. React.js入门笔记(续):用React的方式来思考

    本文主要内容来自React官方文档中的"Thinking React"部分,总结算是又一篇笔记.主要介绍使用React开发组件的官方思路.代码内容经笔者改写为较熟悉的ES5语法. ...

  2. openjdk 完全编译指南

    从openjdk.java.net下载openjdk的软件包,你就获得了所有相关的源码. 强烈建议首先仔细看懂 README-builds.html 指南. 在执行 make all 之前,首先要 执 ...

  3. tyvj1004 滑雪

    描述     trs喜欢滑雪.他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形.为了得到更快的速度,滑行的路线必须向下倾斜.    例如样例中的那个矩形,可以从某 ...

  4. (四)SQL Server分区管理

    一.拆分分区(SPLIT) 在已有分区上添加一个新分区. 如下图所示,将分区03拆分成03和04分区,拆分方式先锁定旧03分区的所有数据,后将旧03分区相关数据迁移到分区04,最后删除旧03上的对应分 ...

  5. nyoj 448 寻找最大数(贪心专题)

    寻找最大数 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 请在整数 n 中删除m个数字, 使得余下的数字按原次序组成的新数最大, 比如当n=920813467185 ...

  6. redis中的key设置过期时间

    EXPIRE key seconds 为给定  key  设置生存时间,当  key  过期时(生存时间为  0  ),它会被自动删除. 在 Redis 中,带有生存时间的  key  被称为『易失的 ...

  7. 利用边框border的属性做小符号

    前两天学习中,发现网站上的一个小符号,以为是插入的img,但找来找去也未发现img的地址.最后问了同学,才得知是用border属性做出来的. 符号如右:  其css代码如下: .fuhao { pos ...

  8. java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead

    java.lang.IllegalStateException: Not allowed to create transaction on sharedEntityManager - use Spri ...

  9. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  10. SpringMVC中遇到的Http400 Bad Request 总结

    在搭建SpringMVC环境,在使用中遇到了多次Bad Request的连接,下面来总结下. 1.参数类型不对,如后台实体类的属性为int,但传来的参数为字符串 2.因为我的粗心,本来是要通过Ajax ...