Entity Framwork CodeFirst 学习笔记一:EF 概念和初次接触CodeFirst
最近在学习EF,在园子里面参考了很多大神的文章,自己也看了些电子书,为了加深印象和快速掌握,特作此笔记和总结。
一、EF 是什么?
Entity Framework的全称为ADO.NET Entity Framework,是在ADO.NET上层实现的ORM(对象关系映射)封装,其技术架构如下图所示:
1、 Entity Framework的使用分为连接配置、关系映射、上下文环境定义、数据持久化 四步。
-
连接配置:如何与数据库进行连接。我们可以通过连接字符串或者代码进行设置和原来连接ADO.Net 连接数据的方式没有什么太大的区别。
- 关系映射(如上图紫色的部分):
(1)SSDL 称之为存储模型,用于描述 Entity Framework 应用程序的存储体模型。
(2)MSL 称之为关系映射,用于描述Entity Framework 用用程序概念模型和存储模型的对于关系。
(3)CSDL 称之为概念模型,它描述构成数据驱动应用程序的概念模型的实体、关系和函数。
他们都是基于XML语言,具体代码可以查看EDMX文件,这里不在赘述。
- 上下文环境定义:DBContext 可以理解为是一个容器,里面有对象与数据表的映射关系以及对象本身。
-
数据持久化:数据持久化就是将内存中的概念模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。
2、EF的三种编程模式:
-
DataBase First:开发模式指以数据库设计为基础,并根据数据库自动生成实体数据模型(edmx 文件)。
-
Model First:是指从建立实体数据模型入手,并依据模型生成数据库,从而驱动整个开发流程。该模式也就是业界流行的面向领域的编程模式,它的优点在于,程序员可以用与设计建模相同的思维来进行代码编写,更符合面向对象的思想。Model First与Database First是互逆的,但最终都是输出数据库和实体数据模型
-
Code First:程序员完全通过手动编码,就可以使用Entity Framewokr技术来实现数据访问。该模式的优点在于,支持POCO(Plain Old CLR Objects,简单传统CLR对象),代码整洁,程序员对代码的控制也更灵活自如。
以下是三种开发模式的比较如下图:
三种编程模式,感觉最方便的还是Code First,因此主要专注于Code First 方式的学习。
二、CodeFirst 的代码结构如下图:
三、小试一把CodeFirst:
为了便于全面理解CodeFirst,我们来做一个简单的例子:
1) 首先我们打开VS2012,建立一个空的解决方案:EFCodeFirstSolution
2) 右击解决方案,添加一个控制台程序:CodeFirstConsole,并用Nuget 添加 Entity Framework 5.0 (内部版本4.4)。
利用Nuget 添加Entity Framework 这个包之后,会自动添加另外两引用分别是:System.ComponentModel.DataAnnotations 和 System.Data.Entity。
同时,还会为我们的控制台应用程序添加两个配置 文件,分别是App.config 和packages.config。我们打开App.config 文件后会发现自动添加了一下两个节点:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> </entityFramework> </configuration>
为什么要增加这样的一个自定义配置节点 entityFramework 呢?
经过查阅:EF4.1开始,可以在配置文件中设置appSettings节点来配置数据库初始化上下文,但在EF 4.3中,使用自定义的EntityFramework部分来处理新的设置,实体框架将仍然承认使用旧格式数据库的初始化设置,但建议在可能的情况下迁移到新的格式。
意思就是在我们今后的配置可以在entityFramework 节点下进行配置,当然也支持老的格式。具体有哪些配置可以参考这篇文章:The Entity Framework Configuration Section
至于 packages.config,是Nuget 为我们生成的,意思是你的程序集下是用了哪些包,我们这个就一个EntityFramework。
3) 配置文件中的 <defaultConnectionFactory> 节点, 默认的是使用本地的数据库,就是安装vs的时候,自带的那个数据库。由于我没有安装,而是单独安装的sql2008,因此需要想配置文件增加一个连接字符串节点,来支持对数据库的访问,在配置文件根节点下增加一个<connectionStrings>节点:
<connectionStrings> <add name="BookContext" connectionString="server=.;Initial Catalog=BookDb;User ID=sa;Password=sasa;Connect Timeout=30;Min Pool Size=16;Max Pool Size=100;" providerName="System.Data.SqlClient" /> </connectionStrings>
5)右击解决方案,添加一个类库 Model,并添加两个类:Author 类 和 Book 类。
using System; using System.Collections.Generic; namespace Model { public class Author { //编号 public int AuthorId { get; set; } //作者姓名 public string Name { get; set; } //作者生日 public DateTime Birthday { get; set; } //作者照片 public byte[] Photo { get; set; } //作者简介 public string Introduce { get; set; } //著作 public List<Book> MyBooks { get; set; } } }
namespace Model { public class Book { //书籍编号 public int BookId { get; set; } //作者编号 public int AuthorId { get; set; } //书籍名称 public string BookName { get; set; } //价格 public decimal Price { get; set; } //是否热销 public bool IsSellFast { get; set; } //作者 public Author Author { get; set; } } }
6)右击解决方案,添加一个类库 DataAccess,也需要引用 EntityFramework及项目中的Model程序集。并添加一个类 BookContext(上下文) 继承于 DBContext,代码如下:
using System.Data.Entity; using Model; namespace DataAccess { public class BookContext : DbContext { public DbSet<Author> Authors { get; set; } public DbSet<Book> Books { get; set; } } }
注意:上下文类名 BookContext 需要与配置文件中连接字符串中的 name="BookContext" 保持一致。(为什么?默认约定,当然也可以不一样,以后文章再说)
7)我们在控制台中程序集中添加 DataAccess 这个项目引用,并在Main 函数编写如下代码:
static void Main(string[] args)
{ try { using (var context = new BookContext()) { context.Database.Create(); } Console.WriteLine("数据库创建成功!"); } catch (Exception ex) { Console.WriteLine("数据库失败!"); Console.Write(ex.Message); } Console.ReadKey(); }
8)运行一下项目,会发现,控制台提示:“数据库创建成功”,打开Sql Server ,会发现果然 创建出来了 BookDb 这个数据库并包含两张表 Author 和 Book。
这就是Code First 的编程方式,直接在代码中创建实体类,就会通过Entity Framwork 在数据库中创建数据库和表。
但是会发现,数据库中的表的字段类型感觉怪怪的。string 类型在数据库中对应成了 navharchar(max),bety[] 类型变成了 varbinary(max),而且两个表还增加了主键和外键关联。其实这都是EF默认的约定所决定的。
能改吗?当然可以,下面的文章我们就来对这些字段类型进行设定和配置。