对现有数据库使用 Code First

此分步演练介绍如何针对现有数据库进行 Code First 开发。 Code First 允许你使用 C# 或 VB.Net 类定义模型。 你可以选择使用类和属性上的特性或使用 Fluent API 来执行其他配置。

先决条件

需要安装 Visual Studio 2012 或 Visual Studio 2013 才能完成本演练

此外,还需要安装适用于 Visual Studio 的实体框架工具的 6.1 版(或更高版本)。 有关安装最新版本的实体框架工具的信息,请参阅获取实体框架

1. 创建现有数据库

通常,当目标为现有数据库时,该数据库已经创建完成,但在本演练中,我们需要创建一个要访问的数据库。

接下来,生成数据库。

  • 打开 Visual Studio

  • “视图”->“服务器资源管理器”

  • 右键单击“数据连接”->“添加连接...”

  • 如果尚未从服务器资源管理器连接到数据库,则需要选择 Microsoft SQL Server 作为数据源

    Select Data Source

  • 连接到 LocalDB 实例,并输入 Blogging 作为数据库名称

    LocalDB Connection

  • 选择“确定”,系统会询问你是否要创建新数据库,请选择“是”

    Create Database Dialog

  • 新数据库现在将出现在服务器资源管理器中,右键单击它并选择“新建查询”

  • 将以下 SQL 复制到新查询中,然后右键单击该查询并选择“执行”

CREATE TABLE [dbo].[Blogs] (
    [BlogId] INT IDENTITY (1, 1) NOT NULL,
    [Name] NVARCHAR (200) NULL,
    [Url]  NVARCHAR (200) NULL,
    CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
);

CREATE TABLE [dbo].[Posts] (
    [PostId] INT IDENTITY (1, 1) NOT NULL,
    [Title] NVARCHAR (200) NULL,
    [Content] NTEXT NULL,
    [BlogId] INT NOT NULL,
    CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([PostId] ASC),
    CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([BlogId]) ON DELETE CASCADE
);

INSERT INTO [dbo].[Blogs] ([Name],[Url])
VALUES ('The Visual Studio Blog', 'http://blogs.msdn.com/visualstudio/')

INSERT INTO [dbo].[Blogs] ([Name],[Url])
VALUES ('.NET Framework Blog', 'http://blogs.msdn.com/dotnet/')

2. 创建应用程序

为简单起见,我们将生成一个使用 Code First 进行数据访问的基本控制台应用程序:

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

 

3. 对模型实施反向工程

我们将使用适用于 Visual Studio 的实体框架工具,来帮助我们生成一些用于映射到数据库的初始代码。 这些工具仅用于生成代码,你也可以根据需要手动键入代码。

  • “项目”->“添加新项...”

  • 从左侧菜单中选择“数据”,然后选择“ADO.NET 实体数据模型”

  • 输入 BloggingContext 作为名称并单击“确定”

  • 此操作将启动实体数据模型向导

  • 选择“数据库中的 Code First”并单击“下一步”

    Wizard One CFE

  • 选择与你在第一部分创建的数据库建立的连接,然后单击“下一步”

    Wizard Two CFE

  • 单击“表”旁边的复选框以导入所有表,然后单击“完成”

    Wizard Three CFE

反向工程完成后,便会向项目中添加许多项,让我们来看看添加了什么。

配置文件

项目中添加了一个 App.config 文件,此文件包含指向现有数据库的连接字符串。

<connectionStrings>
  <add  
    name="BloggingContext"  
    connectionString="data source=(localdb)\mssqllocaldb;initial catalog=Blogging;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"  
    providerName="System.Data.SqlClient" />
</connectionStrings>

你还会注意到配置文件中的一些其他设置,这些是默认的 EF 设置,用于告诉 Code First 在何处创建数据库。 由于我们是要映射到现有数据库,因此将在应用程序中忽略这些设置。

派生上下文

项目中添加了一个 BloggingContext 类。 上下文表示与数据库的会话,允许我们查询和保存数据。 上下文为模型中的每个类型公开一个 DbSet<TEntity>。 你还会注意到默认构造函数使用 name= 语法调用基本构造函数。 这会告诉 Code First 应从配置文件加载要用于此上下文的连接字符串。

public partial class BloggingContext : DbContext
    {
        public BloggingContext()
            : base("name=BloggingContext")
        {
        }

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

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }

使用配置文件中的连接字符串时,应始终使用 name= 语法。 这可以确保,如果连接字符串不存在,实体框架将引发异常,​​而不是按约定创建新数据库。

模型类

最后,项目中还添加了 Blog 和 Post 类。 这些是构成模型的域类。 你将看到应用于类的数据注释,这些注释指定了 Code First 约定与现有数据库结构不一致的配置。 例如,你会在 Blog.Name 和 Blog.Url 上看到 StringLength 注释,因为它们在数据库中的最大长度为 200(Code First 默认使用数据库提供程序支持的最大长度 - SQL Server 中的 nvarchar(max))。

public partial class Blog
{
    public Blog()
    {
        Posts = new HashSet<Post>();
    }

    public int BlogId { get; set; }

    [StringLength(200)]
    public string Name { get; set; }

    [StringLength(200)]
    public string Url { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

4.读取和写入数据

现在我们拥有一个模型,可用它访问某些数据。 在 Program.cs 中实现 Main 方法,如下所示。 此代码创建一个新的上下文实例,然后使用它来插入新的 Blog。 接着,它使用 LINQ 查询从数据库中检索按标题字母顺序排序的所有 Blog

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 Blog
All blogs in the database:
.NET Framework Blog
ADO.NET Blog
The Visual Studio Blog
Press any key to exit...

 

如果数据库发生更改怎么办?

“对数据库使用 Code First”向导旨在生成类的起点集,稍后可以调整和修改这些类。 如果数据库架构发生更改,可以手动编辑类或执行另一个反向工程来覆盖类。

对现有数据库使用 Code First 迁移

若要对现有数据库使用 Code First 迁移,请参阅对现有数据库使用 Code First 迁移

总结

在本演练中,我们研究了使用现有数据库的 Code First 开发。 我们使用适用于 Visual Studio 的实体框架工具对一组类实施了反向工程,这组类映射到数据库并可用于存储和检索数据。