广告
返回顶部
首页 > 资讯 > 精选 >Entity Framework如何使用Code First模式管理数据库
  • 634
分享到

Entity Framework如何使用Code First模式管理数据库

2023-06-29 10:06:01 634人浏览 安东尼
摘要

这篇文章主要为大家展示了“Entity Framework如何使用Code First模式管理数据库”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Entity Fr

这篇文章主要为大家展示了“Entity Framework如何使用Code First模式管理数据库”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Entity Framework如何使用Code First模式管理数据库”这篇文章吧。

一、管理数据库连接

1、使用配置文件管理连接之约定

在数据库上下文类中,如果我们只继承了无参数的DbContext,并且在配置文件中创建了和数据库上下文类同名的连接字符串,那么EF会使用该连接字符串自动计算出数据库的位置和数据库名。比如,我们的数据库上下文定义如下:

using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConventionConfigure.EF{    /// <summary>    /// 继承无参数的DbContext    /// </summary>    public class SampleDbEntities :DbContext    {        public SampleDbEntities()        {            // 数据库不存在时创建数据库            Database.CreateIfNotExists();        }    }}

在配置文件中定义的连接字符串如下:

<connectionStrings>    <add name="SampleDbEntities" connectionString="Data Source=.;Initial Catalog=TestDb;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.sqlClient" /></connectionStrings>

定义的连接字符串中name的value值和创建的数据库上下文类的类名相同,这样EF会使用该连接字符串执行数据库操作,究竟会发生什么呢?

运行程序,Program类定义如下:

using ConventionConfigure.EF;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConventionConfigure{    class Program    {        static void Main(string[] args)        {            using (var context = new SampleDbEntities())            { }            Console.WriteLine("创建成功");            Console.ReadKey();        }    }}

当运行应用程序时,EF会寻找我们的数据库上下文类,即“SampleDbEntities”,并在配置文件中寻找和它同名的连接字符串,然后它会使用该连接字符串计算出应该使用哪个数据库provider,之后检查数据库位置,之后会在指定的位置创建一个名为TestDb.mdf的数据库文件,同时根据连接字符串的Initial Catalog属性创建了一个名为TestDb的数据库。创建的数据库结构如下:

Entity Framework如何使用Code First模式管理数据库

查看创建后的数据库,会发现只有一张迁移记录表。

2、使用已经存在的ConnectionString

如果我们已经有了一个定义数据库位置和名称的ConnectionString,并且我们想在数据库上下文类中使用这个连接字符串,连接字符串如下:

<connectionStrings>    <add name="AppConnection" connectionString="Data Source=.;Initial Catalog=TestDb;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /></connectionStrings>

以上面创建的数据库TestDb作为已经存在的数据库,新添加实体类Student,使用已经存在的ConnectionString查询数据库的Student表,Student实体类定义如下:

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations.Schema;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ExistsConnectionString.Model{    [Table("Student")]    public class Student    {        public int Id { get; set; }        public string Name { get; set; }        public string Sex { get; set; }        public int Age { get; set; }    }}

我们将该连接字符串的名字传入数据库上下文DbContext的有参构造函数中,数据库上下文类定义如下:

using ExistsConnectionString.Model;using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ExistsConnectionString.EF{    public class SampleDbEntities : DbContext    {        public SampleDbEntities()            : base("name=AppConnection")        {        }        // 添加到数据上下文中        public virtual DbSet<Student> Students { get; set; }    }}

上面的代码将连接字符串的名字传给了DbContext类的有参构造函数,这样一来,我们的数据库上下文就会开始使用该连接字符串了,在Program类中输出Name和Age字段的值:

using ExistsConnectionString.EF;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ExistsConnectionString{    class Program    {        static void Main(string[] args)        {            using (var context = new SampleDbEntities())            {                foreach (var item in context.Students)                {                    Console.WriteLine("姓名:"+item.Name+" "+"年龄:"+item.Age);                }            }        }    }}

运行程序,发现会报下面的错误:

Entity Framework如何使用Code First模式管理数据库

出现上面报错的原因是因为数据库上下文发生了改变,与现有数据库不匹配。解决方案:

把数据库里面的迁移记录表删掉或者重命名即可。

重新运行程序,结果如下:

Entity Framework如何使用Code First模式管理数据库

注意:如果在配置文件中还有一个和数据库上下文类名同名的ConnectionString,那么就会使用这个同名的连接字符串。无论我们对传入的连接字符串名称如何改变,都是无济于事的,也就是说和数据库上下文类名同名的连接字符串优先权更大。(即约定大于配置)

3、使用已经存在的连接

通常在一些老项目中,我们只会在项目中的某个部分使用EF Code First,同时,我们想对数据上下文类使用已经存在的数据库连接,如果要实现这个,可将连接对象传给DbContext类的构造函数,数据上下文定义如下:

using ExistsDbConnection.Model;using System;using System.Collections.Generic;using System.Data.Common;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ExistsDbConnection.EF{    public class SampleDbEntities :DbContext    {        public SampleDbEntities(DbConnection con)            : base(con, contextOwnsConnection: false)        {        }        public virtual DbSet<Student> Students { get; set; }    }}

这里要注意一下contextOwnsConnection参数,之所以将它作为false传入到上下文,是因为它是从外部传入的,当上下文超出了范围时,可能会有人想要使用该连接。如果传入true的话,那么一旦上下文出了范围,数据库连接就会立即关闭。

Program类定义如下:

using System;using System.Collections.Generic;using System.Data.Common;using System.Data.SqlClient;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Configuration;using ExistsDbConnection.EF;namespace ExistsDbConnection{    class Program    {        static void Main(string[] args)        {            // 读取连接字符串            string conn = ConfigurationManager.ConnectionStrings["AppConnection"].ConnectionString;            // DbConnection是抽象类,不能直接实例化,声明子类指向父类对象            DbConnection con = new SqlConnection(conn);            using (var context = new SampleDbEntities(con))            {                foreach (var item in context.Students)                {                    Console.WriteLine("姓名:" + item.Name + " " + "年龄:" + item.Age);                }            }            Console.WriteLine("读取完成");            Console.ReadKey();        }    }}

运行程序,结果如下:

Entity Framework如何使用Code First模式管理数据库

二、管理数据库创建

首次运行EF Code First应用时,EF会做下面的这些事情:
1、检查正在使用的DbContext类。
2、找到该上下文类使用的connectionString。
3、找到领域实体并提取模式相关的信息。
4、创建数据库。
5、将数据插入系统。

一旦模式信息提取出来,EF会使用数据库初始化器将该模式信息推送给数据库。数据库初始化器有很多可能的策略,EF默认的策略是如果数据库不存在,那么就重新创建;如果存在的话就使用当前存在的数据库。当然,我们有时也可能需要覆盖默认的策略,可能用到的数据库初始化策略如下:

CreateDatabaseIfNotExists:CreateDatabaseIfNotExists:顾名思义,如果数据库不存在,那么就重新创建,否则就使用现有的数据库。如果从领域模型中提取到的模式信息和实际的数据库模式不匹配,那么就会抛出异常。

DropCreateDatabaseAlways:如果使用了该策略,那么每次运行程序时,数据库都会被销毁。这在开发周期的早期阶段通常很有用(比如设计领域实体时),从单元测试的角度也很有用。

DropCreateDatabaseIfModelChanges:这个策略的意思就是说,如果领域模型发生了变化(具体而言,从领域实体提取出来的模式信息和实际的数据库模式信息失配时),就会销毁以前的数据库(如果存在的话),并创建新的数据库。

MigrateDatabaseToLatestVersion:如果使用了该初始化器,那么无论什么时候更新实体模型,EF都会自动地更新数据库模式。这里很重要的一点是:这种策略更新数据库模式不会丢失数据,或者是在已有的数据库中更新已存在的数据库对象。MigrateDatabaseToLatestVersion初始化器只有从EF4.3才可用。

1、设置初始化策略

EF默认使用CreateDatabaseIfNotExists作为默认初始化器,如果要覆盖这个策略,那么需要在DbContext类中的构造函数中使用Database.SetInitializer方法,下面的例子使用DropCreateDatabaseIfModelChanges策略覆盖默认的策略。数据库上下文类定义如下:

using InitializationStrategy.Model;using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationStrategy.EF{    public class SampleDbEntities : DbContext    {        public SampleDbEntities()            : base("name=AppConnection")        {            // 使用DropCreateDatabaseIfModelChanges策略覆盖默认的策略            Database.SetInitializer<SampleDbEntities>(new DropCreateDatabaseIfModelChanges<SampleDbEntities>());        }        // 添加到数据上下文中        public virtual DbSet<Student> Students { get; set; }    }}

这样一来,无论什么时候创建上下文类,Database.SetInitializer()方法都会被调用,并且将数据库初始化策略设置为DropCreateDatabaseIfModelChanges。

Student领域实体类新增加Email和Address两个属性:

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations.Schema;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationStrategy.Model{    [Table("Student")]    public class Student    {        public int Id { get; set; }        public string Name { get; set; }        public string Sex { get; set; }        public int Age { get; set; }        public string Email { get; set; }        public string Address { get; set; }    }}

Program类定义如下:

using InitializationStrategy.EF;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationStrategy{    class Program    {        static void Main(string[] args)        {            using (var context = new SampleDbEntities())            {                foreach (var item in context.Students)                {                }            }            Console.WriteLine("创建成功");            Console.ReadKey();        }    }}

运行程序后,数据库表结构如下:

Entity Framework如何使用Code First模式管理数据库

注意:如果处于生产环境,那么我们肯定不想丢失已经存在的数据。这时我们就需要关闭该初始化器,只需要将null传给Database.SetInitlalizer()方法,如下所示:

public SampleDbEntities(): base("name=AppConnection"){Database.SetInitializer<SampleDbEntities>(null);}

2、填充种子数据

到目前为止,无论我们选择哪种策略初始化数据库,生成的数据库都是一个空的数据库。但是许多情况下我们总想在数据库创建之后、首次使用之前就插入一些数据。此外,开发阶段可能想以admin的资格为其填充一些数据,或者为了测试应用在特定的场景中表现如何,想要伪造一些数据。

当我们使用DropCreateDatabaseAlways和DropCreateDatabaseIfModelChanges初始化策略时,插入种子数据非常重要,因为每次运行应用时,数据库都要重新创建,每次数据库创建之后在手动插入数据非常乏味。接下来我们看一下当数据库创建之后如何使用EF来插入种子数据。

为了向数据库插入一些初始化数据,我们需要创建满足下列条件的数据库初始化器类:

从已存在的数据库初始化器类中派生数据。
2、在数据库创建期间种子化。

下面演示如何初始化种子数据

1、定义领域实体类
using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations.Schema;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationSeed.Model{    [Table("Employee")]    public class Employee    {        public int EmployeeId { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }    }}
2、创建数据库上下文

使用EF的Code First方式对上面的模型创建数据库上下文:

public class SampleDbEntities : DbContext{    public virtual DbSet<Employee> Employees { get; set; }}

3、创建数据库初始化器类

假设我们使用的是DropCreateDatabaseAlways数据库初始化策略,那么初始化器类就要从该泛型类继承,并传入数据库上下文作为类型参数。接下来,要种子化数据库就要重写DropCreateDatabaseAlways类的Seed()方法,而Seed()方法拿到了数据库上下文,因此我们可以使用它来将数据插入数据库:

using InitializationSeed.Model;using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationSeed.EF{    /// <summary>    /// 数据库初始化器类    /// </summary>    public class SeedingDataInitializer : DropCreateDatabaseAlways<SampleDbEntities>    {        /// <summary>        /// 重写DropCreateDatabaseAlways的Seed方法        /// </summary>        /// <param name="context"></param>        protected override void Seed(SampleDbEntities context)        {            for (int i = 0; i < 6; i++)            {                var employee = new Employee                {                  FirstName="测试"+(i+1),                  LastName="工程师"                };                context.Employees.Add(employee);            }                base.Seed(context);        }    }}

上面的代码通过for循环创建了6个Employee对象,并将它们添加给数据库上下文类的Employees集合属性。这里值得注意的是我们并没有调用DbContext.SaveChanges()方法,因为它会在基类中自动调用。

4、将数据库初始化器类用于数据库上下问类

using InitializationSeed.Model;using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationSeed.EF{    public class SampleDbEntities :DbContext    {        public SampleDbEntities()            : base("name=AppConnection")        {            // 类型传SeedingDataInitializer            Database.SetInitializer<SampleDbEntities>(new SeedingDataInitializer());        }        // 领域实体添加到数据上下文中        public virtual DbSet<Employee> Employees { get; set; }    }}

5、Main方法中访问数据库

using InitializationSeed.EF;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace InitializationSeed{    class Program    {        static void Main(string[] args)        {            using (var context = new SampleDbEntities())            {                foreach (var item in context.Employees)                {                    Console.WriteLine("FirstName:"+item.FirstName+" "+"LastName:"+item.LastName);                }            }            Console.WriteLine("读取完成");            Console.ReadKey();        }    }}

6、运行程序,查看结果

Entity Framework如何使用Code First模式管理数据库

查看数据库

Entity Framework如何使用Code First模式管理数据库

种子数据填充完成。

7、使用数据迁移的方式填充种子数据

使用数据迁移的方式会生成Configuration类,Configuration类定义如下:

namespace DataMigration.Migrations{    using System;    using System.Data.Entity;    using System.Data.Entity.Migrations;    using System.Linq;    internal sealed class Configuration : DbMigrationsConfiguration<DataMigration.SampleDbEntities>    {        public Configuration()        {            AutomaticMigrationsEnabled = false;        }        protected override void Seed(DataMigration.SampleDbEntities context)        {            //  This method will be called after migrating to the latest version.            //  You can use the DbSet<T>.AddOrUpdate() helper extension method            //  to avoid creating duplicate seed data.        }    }}

重写Configuration类的Seed()方法也可以实现插入种子数据,重写Seed()方法:

namespace DataMigration.Migrations{    using DataMigration.Model;    using System;    using System.Data.Entity;    using System.Data.Entity.Migrations;    using System.Linq;    internal sealed class Configuration : DbMigrationsConfiguration<DataMigration.SampleDbEntities>    {        public Configuration()        {            AutomaticMigrationsEnabled = false;        }        protected override void Seed(DataMigration.SampleDbEntities context)        {            //  This method will be called after migrating to the latest version.            //  You can use the DbSet<T>.AddOrUpdate() helper extension method            //  to avoid creating duplicate seed data.            context.Employees.AddOrUpdate(                 new Employee { FirstName = "测试1", LastName = "工程师" },                 new Employee { FirstName = "测试2", LastName = "工程师" }                );        }    }}

使用数据迁移,然后查看数据库结果:

Entity Framework如何使用Code First模式管理数据库

发现使用数据迁移的方式也将种子数据插入到了数据库中。

以上是“Entity Framework如何使用Code First模式管理数据库”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Entity Framework如何使用Code First模式管理数据库

本文链接: https://www.lsjlt.com/news/324050.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Entity Framework如何使用Code First模式管理数据库
    这篇文章主要为大家展示了“Entity Framework如何使用Code First模式管理数据库”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Entity Fr...
    99+
    2023-06-29
  • Entity Framework怎么使用Code First模式管理事务
    今天小编给大家分享一下Entity Framework怎么使用Code First模式管理事务的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后...
    99+
    2023-06-29
  • Entity Framework中怎么使用Code First模式管理视图
    今天小编给大家分享一下Entity Framework中怎么使用Code First模式管理视图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章...
    99+
    2023-06-29
  • Entity Framework怎么使用Code First模式管理存储过程
    这篇文章主要介绍“Entity Framework怎么使用Code First模式管理存储过程”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Entity Framewo...
    99+
    2023-06-29
  • Entity Framework如何使用Code First的实体继承模式
    这篇文章主要介绍Entity Framework如何使用Code First的实体继承模式,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Entity Framework的Code First模式有...
    99+
    2023-06-29
  • Entity Framework使用DataBase First模式实现数据库的增删改查
    在上一篇文章中讲解了如何生成EF的DBFirst模式,接下来讲解如何使用DBFirst模式实现数据库数据的增删改查 一、新增数据 新增一个Student,代码如下: static v...
    99+
    2022-11-13
  • 使用EF的Code First模式操作数据库
    EF的核心程序集位于System.Data.Entity.dll和System.Data.EntityFramework.dll中。支持CodeFirst的位于EntityFrame...
    99+
    2022-11-13
  • Entity Framework中如何使用DataBase First模式实现增删改查
    本篇内容主要讲解“Entity Framework中如何使用DataBase First模式实现增删改查”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Entity ...
    99+
    2023-06-29
  • 如何使用Entity Framework Core对Web项目生成数据库表
    小编给大家分享一下如何使用Entity Framework Core对Web项目生成数据库表,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、引言这篇文章中我们讲解如何在Web项目中使用EntityFr...
    99+
    2023-06-29
  • Entity Framework Core如何使用控制台程序生成数据库表
    这篇文章主要介绍了Entity Framework Core如何使用控制台程序生成数据库表,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、引言我们使用C...
    99+
    2023-06-29
  • EntityFramework使用CodeFirst模式管理数据库
    一、管理数据库连接 1、使用配置文件管理连接之约定 在数据库上下文类中,如果我们只继承了无参数的DbContext,并且在配置文件中创建了和数据库上下文类同名的连接字符串,那么EF会...
    99+
    2022-11-13
  • 如何使用命令行方式管理MySQL数据库
    这篇文章主要为大家展示了“如何使用命令行方式管理MySQL数据库”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用命令行方式管理MySQL数据库”这篇文章吧...
    99+
    2022-10-19
  • 如何用阿里云分布式数据库管理
    简介 在当今互联网时代,数据的规模和复杂度越来越大,传统的单机数据库已经无法满足需求。为了应对这种情况,阿里云推出了分布式数据库管理解决方案,为用户提供了高效、可靠的数据库管理服务。本文将介绍如何使用阿里云分布式数据库管理,帮助用户更好地管...
    99+
    2023-12-29
    阿里 分布式 如何用
  • 阿里云数据库如何使用与管理
    阿里云数据库是阿里云提供的高效、安全、可扩展的数据库服务。本文将详细介绍如何使用和管理阿里云数据库。 一、如何使用阿里云数据库创建数据库:在阿里云控制台中,点击“数据库”选项,然后点击“创建数据库”,输入数据库名和描述,选择数据库类型,设置...
    99+
    2023-12-15
    阿里 如何使用 数据库
  • ADO.NET中如何使用连接模式访问数据库中的数据
    本篇内容介绍了“ADO.NET中如何使用连接模式访问数据库中的数据”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ADO.NET框架支持两种模...
    99+
    2023-06-17
  • 如何使用SQL Pro Studio管理所有数据库
    本篇内容主要讲解“如何使用SQL Pro Studio管理所有数据库”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用SQL Pro Studio管理所有数...
    99+
    2022-10-18
  • 数据库中如何使用数据字典视图管理对象
    小编给大家分享一下数据库中如何使用数据字典视图管理对象,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 一、数据字典的分类 1...
    99+
    2022-10-18
  • 如何使用Visual Studio 2010统一管理数据库对象
    这篇文章主要讲解了“如何使用Visual Studio 2010统一管理数据库对象”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Visual Studio 2010统一管理数据库对象...
    99+
    2023-06-17
  • 如何在OS X上使用Sequel Pro来管理MySQL数据库
    这期内容当中小编将会给大家带来有关如何在OS X上使用Sequel Pro来管理MySQL数据库,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。另外一个选择就是 MySQL...
    99+
    2022-10-19
  • java中如何使用Flyway管理数据库的版本变更
    这篇文章给大家分享的是有关java中如何使用Flyway管理数据库的版本变更的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1. 前言随着项目的不断迭代,数据库表结构、数据都在发生着变化。甚至有的业务在多环境版本并...
    99+
    2023-06-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作