深入了解Entity Framework框架及访问数据的几种方式

一、前言

1、Entity Framework概要

Entity Framework是微软以ADO.NET为基础所发展出来的对象关系映射(O/R Mapping)解决方案。该框架曾经为.NET Framework的一部分,但Version 6之后从.NET Framework分离出来,可通过NuGet获取。

Entity Framework利用抽象化数据结构的方式,将每个数据库对象都转换成应用程序对象 (Entity),而数据字段都转换为属性 (Property),关系则转换为结合属性 (Association),让数据库的E/R(实体-联系图)模型完全的转成对象模型,让程序设计师能用最熟悉的编程语言来调用访问。

2、什么是ORM

对象-关系映射(Object Relational Mapping,简称ORM),用来把对象模型表示的对象映射到基于SQL的关系模型数据库结构中去。这样在具体的操作实体对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作实体对象的属性和方法。即用操作对象的方式来操作数据库。

其它ORM框架:Dapper、NHibernate等。

3、Entity Framework使用说明

①、EF是建立在ADO.NET框架之上的,底层使用的是ADO.NET方法和类来执行数据操作,具体如下图所示:

②、EF支持SQL Server、MySQL、Oracle等主流数据库。

③、EF采用约定大于配置的框架原则,能遵守约定就不要去配置。

④、EF开发数据库的两种形式先建数据库或者先建模型

⑤、EF三种开发模式:

◆ DataBase First (数据库优先)

如果数据库已存在,可以使用VS自动生成数据模型以及相关的edmx文件

使用简单、方便,适用于数据库会频繁修改来满足新的需求。会出现修改了数据库在程序中更新EF不起作用等问题。

 Model First (模型优先)

如果数据库未创建,可以在VS中利用Model设计数据库,通过设计器生成映射信息(edmx文件),并生成数据库。开发中很少使用。

 Code First (代码优先)(*)

可以通过设计的数据模型自动生成数据库,也可以通过已存在的数据库生成数据模型,进行数据库映射,都没有edmx文件。

完全控制代码,即没有自动生成的模型和上下文代码。

数据库由EF帮助生成,当修改模型后,EF使用DB Miguration自动帮助修改数据库,但也可以禁用Miguration,手动创建(推荐)

上图中前三种分别是DataBase First、Model First 和Code First,而第四种也是Code First。

那么第三个和第四个到底有什么区别?项目中如何使用?下面将会重点讲解。(*)

⑥、EF三种开发模式使用比较,如下图所示:


 


说明


使用


Database First (数据库优先)


数据库已存在(生成edmx文件)


数据库频繁改变


Model First (模型优先)


数据库未存在(生成edmx文件)


开发中很少使用


Code First(代码优先)


数据库存在/未存在(没有生成edmx文件)


完全控制代码

可以禁用数据迁移

手动修改数据库和实体类

二、Entity Framework 访问数据三种方式

1、DataBase First模式

1.1、创建

①、创建一个应用程序选择(.NET Framework类库),选择“添加” ->“新建项”->点击“数据”->选择“ADO.NET 实体数据模型”,具体如下图所示:

②、选择模型内容来自“数据库的EF设计器”,具体如下图所示:

③、点击新建连接如图二所示,选择数据库地址、连接方式和数据库,然后配置数据连接字符串如图一所示,具体如下图所示:

④、选择要映射的“PersonInfo”表,具体如下图所示:

⑤、创建完模型之后,你会发现Visual Studio自动生成了“Person”实体类和一个“EntityModelContext”数据库上下文操作类,具体如下图所示:

1.2、应用

查询数据,创建控制台应用程序,通过NuGet包管理器,添加“Entity Framework”引用,然后配置相应的App.config的数据库连接,创建测试代码:

static void Main(string[] args)
{
    //实例化数据库上下文
    using (var dbContext=new DemoDBEntities() )
    {
        //使用Lambda表达式查询数据
        var info = dbContext.PersonInfo.Where(i => i.Name == "ZhangSan").ToList();

        //使用Linq语句查询
        var info1 = from i in dbContext.PersonInfo
                    where i.ID == 1
                    select i;

        //获取查询结果
        foreach (var item in info)
        {
            Console.WriteLine(" Lambda方式的查询结果:姓名:" + item.Name +" 年龄:"+item.Age);
        }

        //foreach (var item in info1)
        //{
        //    Console.WriteLine(" Linq  方式的查询结果:姓名:" + item.Name + " 年龄:" + item.Age);

        //}
        Console.ReadLine();
    }
}

结果如下图所示:

1.3、说明

Database First是以数据库为中心的开发方式;

使用这种模式必须要先设计和创建数据库,然后使用VS在已有数据库的基础上创建ADO.NET实体数据模型,然后使用EF访问和操作数据库;

如果数据库表结构发生改变后,只需在模型设计视图空白处右键,选择“从数据库更新模型”接着按照向导操作即可完成模型更新;

上面只是演示了一个查询的小功能,EF的强大机制还需动手实践和操作。

2、Model First模式

2.1、创建

①、创建一个应用程序选择(.NET Framework类库),选择“添加” ->“新建项”->点击“数据”->选择“ADO.NET 实体数据模型”,具体如下图所示:

②、选择模型内容来自“空EF设计器模型”,具体如下图所示:

③、开始设计实体,在空白处右击,添加实体(UserInfo)和实体的属性(eg:ID、Name、Age)等 ,具体如下图所示:

④、实体模型设计完成,接下来要生成数据库,选择“根据模型生成数据库”,具体如下图所示:

⑤、创建数据库,填写相应的数据库连接属性,具体如下图所示:

⑥、EF模型选择和Visual Studio自动生成DDL文件,具体如下图所示:

⑦、选择自动创建的SQL脚本,此时数据已生成,执行脚本生成所需要的表,具体如下图所示:

⑧、打开数据库,可以看到创建的数据库以及表,具体如下图所示:

2.2、应用

查询数据,创建控制台应用程序,通过NuGet包管理器,添加“Entity Framework”引用,然后配置相应的App.config的数据库连接,创建测试代码:

static void Main(string[] args)
{
    using (var dbContext = new ModelFirstContainer())
    {
        //添加
        UserInfo userModel = new UserInfo();
        userModel.Name = "WangWu";
        userModel.Age = 18;
        dbContext.UserInfo.Add(userModel);
        dbContext.SaveChanges();

        //Linq查询
        var list = from i in dbContext.UserInfo
                   where i.Name == "ZhangSan"
                   select i;

        //Lambda 表达式查询
        var info = dbContext.UserInfo.Where(i => i.Name == "ZhangSan").ToList();

        //获取数据
        foreach (var item in list)
        {
            Console.WriteLine(" Linq  方式的查询结果:姓名:" + item.Name + " 年龄:" + item.Age);
        }

        foreach (var item in info)
        {
            Console.WriteLine(" Lambda方式的查询结果:姓名:" + item.Name + " 年龄:" + item.Age);
        }
        Console.ReadLine();
    }
}

结果如下图所示:

2.3、说明

ModelFirst模式是实体模型先行的开发方式;

先设计实体,然后根据实体再去生成数据库并且进行相应的操作;

使用这种方式的唯一原因就是想体验视觉实体设计器。

3、Code First模式

文章开始说到的Code First模式有两种选择一种是“空CodeFirst模型”,另一种是“来自数据库的CodeFirst”,具体如下图所示:

上图分别对两种模式进行了描述,那它们到底该如何使用以及区别是什么?请看下面的例子。

3.1、空Code First模式

1、创建

①、创建一个应用程序选择(.NET Framework类库),选择“添加” ->“新建项”->点击“数据”->选择“ADO.NET 实体数据模型”,具体如下图所示:

②、选择模型内容来自“空Code First模型”,具体如下图所示:

③、点击完成,具体如下图所示:

通过上图我们可以看到生成相应的数据库上下文以及数据库连接字符串。(可以根据自己的需求进行修改配置以及添加对应的实体)

2、应用

1)、连接配置文件(修改数据库连接字符串,改成我们要存放数据库服务器名)

<connectionStrings>
           <add name="CodeDB" connectionString="data source=.;initial catalog=CodeDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"                 providerName="System.Data.SqlClient" />
</connectionStrings>

2)、代码示例:

static void Main(string[] args)
{
    using (var dbContext=new CodeDB() )
    {

        UserInfo userModel = new UserInfo();
        userModel.Name = "ZhangSan";
        dbContext.UserInfo.Add(userModel);
        dbContext.SaveChanges();
        Console.ReadKey();
    }
}

3)、运行上面代码,“空Code First模型”,生成的数据库如下图所示:

从上图可以看出:

1、自动生成数据库CodeDB;

2、数据库中生成一张叫__MigrationHistory 的表(是用于记录代码迁移的历史记录,也是代码迁移模式的开关,后面会聊);

3、数据库中还创建一张实体类型(UserInfoes的表),包括字段名以及字段类型等信息;

4、利用代码添加一条数据到UserInfoes的表中。

以上就是通过空Code First模式创建的数据库以及表(通过代码实现数据的创建以及表添加)上面的示例操作到这一步都显示正常,但是我们在实际开发中,

有时需要向数据库中添加表以及修改表字段和属性,那现在我们在实体的代码中添加一个Age字段,具体如下所示:

public class UserInfo
{
    public int Id { get; set; }
    public string Name  { get; set; }

    //实体中添加Age字段
    public string Age { get; set; }
}

现在运行程序

程序出现异常,那我们来看看什么意思“从数据库创建以来支持CODEDB上下文的模型发生了变化,考虑使用代码第一迁移来更新数据库”,

说的就是模型与实际数据库结构不一致,需要使用 Code First 中的数据迁移功能来解决问题,下面我们就来看看数据迁移。

3、数据迁移的用法

1、什么情况需要进行数据迁移

 在开发中使用空Code First模式,如果涉及到数据表的变更以及字段修改等操作,该如何做呢?当然如果是新项目,删除数据库,然后重新生成就行了,

 那么如果是线上的项目,数据库中已经有数据了,那么删除数据库重新生成就不行了,那么该如何解决呢?EF Code First提供了一种数据迁移的操作。

 2、如何进行数据迁移

●  手动迁移

当模型与实际数据库结构不一致时,就需要使用数据迁移。数据迁移我们需要掌握三个方法,它们分别是:

1) 在当前项目中启用数据迁移 Enable-Migrations

2) 添加迁移版本 Add-Migration 版本名称

3) 更新数据库 Update-Database

第一步,选择需要启用数据迁移的项目,打开“视图”->“其它窗口”->“程序包管理器控制台” 或者可以按快捷键 Alt+V,E,O,

然后输入命令:Enable-Migrations,具体如下图所示:

显示当前项目中已启用数据迁移,项目中会多出 Migrations文件夹以及相关代码(Migrations文件夹主要是数据迁移的信息),具体如下图所示

 第二步由于我们的模型已经发生了改变,所以需要添加一个新的迁移版本,在程序包管理控制台

 执行如下命令:Add-Migration v1.0 ( 其中的v1.0表示版本号,名称可以自定义),此时再看项目中就会多出一个文件:

    第三步通过数据迁移代码可以看到数据库是如何进行更新和修改,想要让数据库发生改变,为表添加一个Age字段,

 还是需要用到第三个命令:Update-Database(执行成功之后,表中就会添加一个 Age字段)

完成以上三个步骤,此时的模型与实际数据库结构已经一致,再运行程序,程序就不会报错了。

●  自动迁移

上面我们利用命令方式手动完成数据迁移的,那么如果我们在实际开发中,每次修改完模型都要这样更新数据库吗?如果表中有数据时,是否会丢失数据?

当然还有一种方式自动迁移,我们需要在项目中启用Migrations,然后在Configuration类中设置AutomaticMigrationsEnabled设置为true

还需要在DbContext构造函数中写上这句

Database.SetInitializer(new MigrateDatabaseToLatestVersion<EntityContext, Configuration>("DBConnectionString")),

通过构造函数把数据库更新为最新,具体如下图所示:

说明:如果不喜欢自动迁移,可以手工完成这个操作。手工迁移的好处后,可以随时退回到某个指定的迁移版本。迁移文件也可以进行版本管理有利于团队开发。

通过使用Code First模式创建出来的数据库,默认是开启了数据迁移,如果我们模型进行了修改,那么就需要在项目中开启数据迁移,进行模型和数据库同步。

数据迁移有分为手动迁移和自动迁移,上面已讲解,可以根据自己的项目需求进行选择。

但是在实际开发中进行数据迁移难免会出现一些问题,如果数据库存有大量数据,迁移过程有可能导致数据丢失,每次更新模型都要进行数据迁移,

给我们开发带来很多不便,但是还是想用代码先行模式开发,那么我就可以使用“来自数据库的Code First”的方式,默认是关闭数据迁移的,

方便我们随时修改数据库以及模型,提高开发效率,推荐使用,请看下面讲解。

3.2、来自数据库的Code First

1、场景

◆ 数据库已存在并且不想启用数据库迁移;

◆ 习惯通过手动修改实体类,手动修改数据库表结构,来同步数据库和模型;

◆ 实现代用优先原则。

2、创建

①、创建一个应用程序选择(.NET Framework类库),选择“添加” ->“新建项”->点击“数据”->选择“ADO.NET 实体数据模型”,具体如下图所示:

②、选择模型内容来自“来自数据库的Code First”,具体如下图所示:

③、选择连接建据库,填写相应的数据库连接属性,具体如下图所示:

④、选择需要的数据库对象,具体如下图所示:

⑤、点击完成,项目中生成相应的数据库上下文,具体如下图所示:

3、应用
static void Main(string[] args)
{
    using (var dbContext=new CodeEntity() )
    {
        PersonInfo userModel = new PersonInfo();
        userModel.Name = "LiSi";
        dbContext.PersonInfo.Add(userModel);
        dbContext.SaveChanges();
        Console.ReadKey();
    }
}
4、说明

通过上面的示例代码运行我们可以看到,“来自数据库的Code First”,我们可以通过手动创建数据库,手动修改实体,方便我们随时修改数据库和实体,

而且还不会生成__MigrationHistory 的表,也不用进行数据迁移,这种方式可以更好地提现Code First的好处。

3.3 、Code First 模式总结

1)Code First模式中,当模型与表结构不一致时,程序会报错,有两种方式使模型和表结构一致,一种是手动修改模型代码和表结构,另一种是使用数据迁移功能。

这两种方式不是想选哪一个就选哪一个,取决于是否使用了数据迁移 。

2)使用空Code First模型创建的数据库默认是开启数据迁移的;

3)使用来自数据库的Code First模式中的数据库,默认是关闭数据迁移的。

4)使用来自数据库的Code First模式,通过手动改写实体类,手动改数据库表结构,来同步模型与实际表结构,可以完全自己控制代码,推荐使用。

三、Entity Framework 总结

    Database First:用于数据库已经存在,可以使用VS自动生成数据模型,已经相关的edmx信息。

    Model First:数据库未创建,可以在VS中利用Model设计数据库,通过设计器生成映射信息(edmx文件),并自动生成数据库。

    Code First:通过设计的数据模型自动生成数据库,不需要额外edmx文件,也可通过已存在的数据库生成数据模型,进行数据库映射,同样不需要edmx文件。

优秀是一种习惯,欢迎大家关注学习

原文地址:https://www.cnblogs.com/1312mn/p/9239419.html

时间: 2024-10-11 13:16:28

深入了解Entity Framework框架及访问数据的几种方式的相关文章

在Entity Framework 7中进行数据迁移

(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注.) 题记:虽然EF7重新设计了Entity Framework,不过也还是能够支持数据迁移的. Entity Framework 7是微软ORM框架的一次重生,变得更加轻量级.因而默认情况是没有开启数据迁移(Migration)功能的,也即创建出来的数据库默认不会包含“__MigrationHistory”表.在这种情况下,数据模型的变更,需要你手动(通过SQL脚本)去修改对应的数据库结构.当然,你还是可以启用自

两个Activity之间共享数据、互相访问的另一种方式的实现

本帖最后由 勇敢的心_ 于 2010-9-29 11:51 编辑本人从windows编程转过来学习Android开发,一直在想如果两个Activity之间能够像C#或delphi中的Form一样,可以直接访问其成员(字符.数值.成员对象等),并能调用其公开的方法,那应该比用Intent来传递数据直接方便的多,于是偿试了如下办法,测试基本没有问题,发出来大家讨论一下.本人学习android不久,幼稚的地方希望大家不要见笑原理:假设有两个Activity:ActivityMain 和 Activit

POST提交数据的四种方式

四种常见的 POST 提交数据方式 HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文主要讨论 POST 提交数据的几种方式. 我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范.规范把 HTTP 请求分为三个部分:请求首行(状态行).请求头.请求体(消息主体).类似于下面这样: <method> <

控制器读取视图表单中的数据的几种方式

上次分享了控制器向视图传递数据的4种方式,今天再来给大家讲讲MVC视图中的数据如何提交到控制器. 我们可以通过以下几种方式提交数据到控制器: 1.通过Request.Form读取表单数据 在 控制器动作方法(Action)中,POST方法提交的表单可以使用Request.Form读取其中的数据: <html> <head></head> <body> <form> <input type="text" name=&quo

关于Mysql删除表数据的两种方式对比

1.delete from table_name 一行一行删除,只删除表数据,auto_increament仍停留在最后一天数据的下一个值. 2.truncate table_name 快捷删除表数据.先删除整个表,然后重新建表结构.auto_increament从1开始. 关于Mysql删除表数据的两种方式对比,布布扣,bubuko.com

ios网络学习------4 UIWebView的加载本地数据的三种方式

UIWebView是IOS内置的浏览器,可以浏览网页,打开文档  html/htm  pdf   docx  txt等格式的文件.  safari浏览器就是通过UIWebView做的. 服务器将MIME的标识符等放入传送的数据中告诉浏览器使用那种插件读取相关文件. uiwebview加载各种本地文件(通过loadData方法): - (void)viewDidLoad { [super viewDidLoad]; [self setupUI]; NSString *path = [[NSBund

向服务器传json数据的两种方式

接触到了向服务器传JSON数据,那么怎么把参数以JSON的形式,传到服务器呢.下面来说说,json字符串的得到方法.一共有两种方式来得到Json的字符串.当然,向服务器上传,不能传字符串,是要转成NSData的,也就是二进制的形式.这个在此不讨论,只说,怎么得到json的字符串. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. //第一种方法,是把要传的参数

SpringMVC返回json数据的三种方式

SpringMVC返回json数据的三种方式:http://blog.csdn.net/shan9liang/article/details/42181345 上述第三种方法:可能会出现这个jar包没有的情况,引入即可,下面pom引入即可 java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException

获取数据库增量数据的几种方式

获取数据库增量数据的几种方式 a.触发器:在要抽取的表上建立需要的触发器,一般要建立插入.修改.删除三个触发器,每当源表中的数据发生变化,就被相应的触发器将变化的数据写入一个临时表,抽取线程从临时表中抽取数据,临时表中抽取过的数据被标记或删除.触发器方式的优点是数据抽取的性能较高,缺点是要求业务表建立触发器,对业务系统有一定的影响. b.时间戳:它是一种基于快照比较的变化数据捕获方式,在源表上增加一个时间戳字段,系统中更新修改表数据的时候,同时修改时间戳字段的值.当进行数据抽取时,通过比较系统时