我的编程空间,编程开发者的网络收藏夹
学习永远不晚

使用EF的Code First模式操作数据库

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

使用EF的Code First模式操作数据库

EF的核心程序集位于System.Data.Entity.dll和System.Data.EntityFramework.dll中。
支持CodeFirst的位于EntityFramework.dll中。
通常使用NuGet Package Manager来添加这些程序集。

如果没有数据库:

  • 1、先写代码,自动创建数据库。
  • 2、如果代码有变化,自动删除数据库重建,或者是使用迁移功能更改已有数据库。

如果已有数据库:

  • 使用EF PowerTools反向工程生成模型。

下面的示例程序中将通过一个控制台程序演示如何通过Code First模式创建一个数据库,并执行简单的增删改查操作。

一、创建一个控制台应用程序,命名为CodeFirstAppDemo。

二、安装Entity Framework,添加对Code First的支持

1、通过Nuget包管理器控制台进行安装

选择“工具”->Nuget程序包管理器->程序包管理器控制台,下面将会打开程序包管理器控制台窗口:

输入命令:Install-Package EntityFramework进行安装。

2、通过可视化界面进行安装

在项目上面右键选择管理Nuget程序包:

选择EntityFramework,点击“安装”按钮进行安装:

安装完以后,项目引用里面将会出现EntityFramework程序集:

如果安装完以后,项目引用里面没有这两个dll,一定要检查为什么没有安装成功,因为下面的程序中要用到DbContext类,该类位于EntityFramework程序集中。

三、根据.NET中的类来创建数据库。

经过上面的步骤之后,我们就可以开始写代码了。在写代码之前,要始终记得:每个实体类就是相应的数据表中的一行数据,该实体类的属性对应的就是数据表中的列。

1、创建EDM实体数据模型

在项目上右键->添加->新建文件夹,命名为Models,存放相应的实体类。在Models文件夹下面新建两个实体类:Category和Product,Category里面包含一个类型是Product的集合属性,两个实体类的属性分别如下:

Category类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo.Models
{
    /// <summary>
    /// 产品分类表
    /// </summary>
    public class Category
    {
        /// <summary>
        /// 分类ID
        /// </summary>
        public int CategoryId { get; set; }

        /// <summary>
        /// 分类名称
        /// </summary>
        public string CategoryName { get; set; }

        /// <summary>
        /// 产品
        /// </summary>
        public List<Product> ProductList { get; set; }
    }
}

Produce类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo.Models
{
    /// <summary>
    /// 产品类
    /// </summary>
    public class Product
    {
        /// <summary>
        /// 产品Id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 产品名称
        /// </summary>
        public string ProductName { get; set; }

        /// <summary>
        /// 产品价格
        /// </summary>
        public decimal Price { get; set; }

        /// <summary>
        /// 出版日期
        /// </summary>
        public DateTime PublicDate { get; set; }
    }
}

我们需要定义和期望的数据库类型相匹配的属性。上面的例子中,.Net中的int类型会映射到SQL Server中的int类型,string类型会映射到所有可能的字符类型,decimal和Datetime也和SQL Server中的一样。大多数时候,我们不需要关心这些细节,我们只需要编写能够表示数据的模型类就行了,然后使用标准的.Net类型定义属性,其他的就让EF自己计算出保存数据所需要的RDBMS类型。

2、创建数据上下文

接下来我们创建数据库上下文,它是数据库的抽象。目前,我们有两张张表Category和Product,因而要给该数据库上下文定义两个属性来代表这两张表。再者,一张表中一般肯定不止一条数据行,所以我们必须定义一个集合属性,EF使用DbSet来实现这个目的。

在项目上右键->添加->新建文件夹,命名为EFDbContext,用来存放数据库上下文类。添加类Context,并使该类继承自DbContext类。DbContext位于EntityFramework.dll程序集中。

Context类代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using CodeFirstAppDemo.Models;

namespace CodeFirstAppDemo.EFDbContext
{
    public class Context : DbContext
    {
        /// <summary>
        /// 1、创建构造函数,构造函数继承DbContext类的构造函数,通过DbContext类的构造函数创建数据库连接
        /// 2、DbContext类的构造函数里面的参数是数据库连接字符串,通过该连接字符串去创建数据库
        /// </summary>
        public Context()
            : base("name=FirstCodeFirstApp")
        { }

        //2、定义数据集合:用于创建表
        public DbSet<Category> Categorys { get; set; }

        public DbSet<Product> Products { get; set; }
    }
}

在这里,DbContext是所有基于EF的上下文基类,通过它可以访问到数据库中的所有表。上面的代码中调用了父类的构造函数,并且传入了一个键值对,键是name,值是CodeFirstApp,这个键值对是定义在应用程序的配置文件中的,取决于你的应用程序类型,可能是app.config或者web.config。在我们的控制台应用程序中就是app.config。

在app.config文件的configuration节点下(不要在第一个节点下,否则会报错)添加:

<connectionStrings>
    <add name="CodeFirstApp" connectionString="Server=.;Database=CodeFirstApp;User Id=sa;Password=test" providerName="System.Data.SqlClient"/>
</connectionStrings>

3、使用EF提供的API访问数据库来创建数据库

using CodeFirstAppDemo.EFDbContext;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用数据库上下文Context
            using (var context = new Context())
            {
                 // 如果数据库不存在,则调用EF内置的API创建数据库
                if (context.Database.CreateIfNotExists())
                {
                    Console.WriteLine("数据库创建成功!");
                }
                else
                {
                    Console.WriteLine("数据库已存在");
                }
            }

            Console.ReadKey();
        }
    }
}

最后,只需要确保连接字符串没有问题就可以了。运行程序,然后打开SSMS进行确认数据库是否创建成功即可。

这时可以清楚地看到,数据库表名是自定义数据库上下文中DbSet<T>属性中T类型的复数形式。例如T类型是Product,那么生成的表名就是Products,而表中的列是数据模型的属性。此外,注意以下列的类型。EF默认将id作为了主键,string类型的ProductName在数据库中的类型是nvarchar(max),这些都是在使用EF时必须注意的命名规格。

四、执行简单的CRUD操作

1、创建记录-Create

你可以这样认为,将对象添加到集合中就相当于将数据插入到数据库相应的表中。我们使用DbSet的Add方法来实现新数据的添加,而DbContext类的SaveChanges方法会将未处理的更改提交到数据库,这是通过检测上下文中所有的对象的状态来完成的。所有的对象都驻留在上下文类的DbSet属性中。比如,例子中有一个Products属性,那么所有的产品数据都会存储到这个泛型集合属性中。数据库上下文会跟踪DbSet属性中的所有对象的状态,这些状态有这么几种:Deleted、Added、Modified和Unchanged。如果你想在一个表中插入多行数据,那么只需要添加该表对应的类的多个对象的实例即可,然后使用SaveChanges方法将更改提交到数据库,该方法是以单事务执行的。最终,所有的数据库更改都会以单个工作单元持久化。既然是事务,那么就允许将批量相关的更改作为单个操作提交,这样就保证了事务一致性和数据完整性。

修改Main方法如下:

using CodeFirstAppDemo.EFDbContext;
using CodeFirstAppDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用数据库上下文Context
            using (var context = new Context())
            {
                 // 如果数据库不存在,则调用EF内置的API创建数据库
                if (context.Database.CreateIfNotExists())
                {
                    Console.WriteLine("数据库创建成功!");
                }
                else
                {
                    Console.WriteLine("数据库已存在");
                }

                #region EF 添加数据
                //添加数据
                var cate = new List<Category> {
                   new Category{
                    CategoryName="文学类",
                    ProductList=new List<Product>{
                          new Product
                   {
                     ProductName="百年孤独",
                     Price=37.53m,
                     PublicDate=new DateTime(2011,6,1)

                   },
                     new Product
                   {
                     ProductName="老人与海",
                     Price=37.53m,
                     PublicDate=new DateTime(2010,6,1)

                   }
                      }
                   },
                    new Category{
                    CategoryName="计算机类",
                    ProductList=new List<Product>{
                          new Product
                   {
                    ProductName="C#高级编程第九版",
                     Price=48.23m,
                     PublicDate=new DateTime(2016,2,8)
                   },
                    new Product
                   {
                     ProductName="Oracle从入门到精通",
                     Price=27.03m,
                     PublicDate=new DateTime(2014,7,9)
                   }
                      }
                   }

                };

                //将创建的集合添加到上下文中
                context.Categorys.AddRange(cate);
                //调用SaveChanges()方法,将数据插入到数据库
                context.SaveChanges();
                #endregion
            }

            Console.ReadKey();
        }
    }
}

这里需要注意两点:
1、不需要给Product.Id属性赋值,因为它对应到SQL Server表中的主键列,它的值是自动生成的,当SaveChanges执行以后,打断点就能看到返回的Product.Id已经有值了。
2、Context的实例用了using语句包装起来,这是因为DbContext实现了IDisposable接口。DbContext还包含了DbConnection的实例,该实例指向了具有特定连接字符串的数据库。在EF中合适地释放数据库连接和ADO.NET中同等重要。

2、查询记录-Retrieve

查询时也是直接通过DbSet进行查询的:

using CodeFirstAppDemo.EFDbContext;
using CodeFirstAppDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用数据库上下文Context
            using (var context = new Context())
            {
                 // 如果数据库不存在,则调用EF内置的API创建数据库
                if (context.Database.CreateIfNotExists())
                {
                    Console.WriteLine("数据库创建成功!");
                }
                else
                {
                    Console.WriteLine("数据库已存在");
                }

                #region EF 2查询数据

                //查询方式1
                var products = from p in context.Categorys select p;
                foreach (var item in products)
                {
                    Console.WriteLine("分类名称:" + item.CategoryName);
                }

                //查询方式2
                //延迟加载 cates里面没有数据
                var cates = context.Categorys;
                //执行迭代的时候才有数据
                foreach (var item in cates)
                {
                    Console.WriteLine("分类名称:" + item.CategoryName);
                }
                #endregion
            }

            Console.ReadKey();
        }
    }
}

如果像下面那样打一个断点,你会看到一个结果视图,点击类似刷新的图标会看到查询的结果,这个东西道出了EF中很重要的一个概念:延迟加载。此时还没有真正查询数据库,只有当LINQ的查询结果被访问或者被枚举时才会将查询命令发送到数据库。EF是基于DbSet实现的IQueryable接口来处理延迟查询的。

3、更新记录-Update

在SQL中,更新需要执行Update命令。而在EF中,我们要找到DbSet实体集合中要更新的对象,然后修改其属性,最后调用SaveChanges方法即可。

using CodeFirstAppDemo.EFDbContext;
using CodeFirstAppDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用数据库上下文Context
            using (var context = new Context())
            { 
                 // 如果数据库不存在,则调用EF内置的API创建数据库
                if (context.Database.CreateIfNotExists())
                {
                    Console.WriteLine("数据库创建成功!");
                }
                else
                {
                    Console.WriteLine("数据库已存在");
                }

                #region EF 更新数据

                var products = context.Products;
                if (products.Any())
                {
                    // 查询产品名称是“百年孤独”的产品
                    var toUpdateProduct = products.First(p => p.ProductName == "百年孤独");
                    // 修改查询出的产品名称
                    toUpdateProduct.ProductName = "唐诗三百首";
                    // 调用SaveChanges()方法保存数据
                    context.SaveChanges();
                }

                #endregion
            }

            Console.ReadKey();
        }
    }
}

这里我们使用了Any()扩展方法来判断序列中是否有元素,然后使用First()扩展方法来找到Name=="百年孤独"的元素,然后给目标对象的Name属性赋予新值,最后调用SaveChanges()方法保存数据。

4、删除记录-Delete

要删除一条数据,就要先找到这条数据.

using CodeFirstAppDemo.EFDbContext;
using CodeFirstAppDemo.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;

namespace CodeFirstAppDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用数据库上下文Context
            using (var context = new Context())
            {
                 // 如果数据库不存在,则调用EF内置的API创建数据库
                if (context.Database.CreateIfNotExists())
                {
                    Console.WriteLine("数据库创建成功!");
                }
                else
                {
                    Console.WriteLine("数据库已存在");
                }

                #region EF 删除数据

                var products = context.Products;
                // 先根据ProductName找到要删除的元素
                var toDeleteProduct = context.Products.Single(p => p.ProductName == "唐诗三百首");
                if (toDeleteProduct != null)
                {
                // 方式1:使用Remove()方法移除
                context.Products.Remove(toDeleteProduct);
                // 方式2:更改数据的状态
                context.Entry(toDeleteProduct).State = EntityState.Deleted;
                // 最后持久化到数据库
                context.SaveChanges();

                #endregion
            }

            Console.ReadKey();
        }
    }
}

到此这篇关于使用EF的Code First模式操作数据库的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

使用EF的Code First模式操作数据库

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

下载Word文档

猜你喜欢

EF中怎么使用Code First模式生成单数形式表名

今天小编给大家分享一下EF中怎么使用Code First模式生成单数形式表名的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。当
2023-06-29

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

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

EF中怎么使用Code First模式给实体类添加复合主键

这篇文章主要介绍“EF中怎么使用Code First模式给实体类添加复合主键”,在日常操作中,相信很多人在EF中怎么使用Code First模式给实体类添加复合主键问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
2023-06-29

Entity Framework如何使用Code First的实体继承模式

这篇文章主要介绍Entity Framework如何使用Code First的实体继承模式,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Entity Framework的Code First模式有三种实体继承模式1、
2023-06-29

java 使用策略模式操作JDBC数据库

java 使用策略模式操作JDBC数据库1:构造一个操作数据库的工具类,可以获得连接和释放连接public class DBUtil { private static Connection conn = null; static {
2023-05-31

怎么使用DataBase First模式实现数据库的增删改查

本文小编为大家详细介绍“怎么使用DataBase First模式实现数据库的增删改查”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用DataBase First模式实现数据库的增删改查”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢
2023-06-29

Python操作MySQL数据库—pymysql库(可直接使用的模板通用操作)

Python与MySQL数据库交互 1.DB-API:(DB是data;API是方法,接口) Python与数据库的交互: 在没有DB-API之前,各数据库之间的应用接口非常混乱,实现各不相同,如果项目需要更换数据库,基本上需要把所有和
2023-08-16

ASP.NET Core如何使用EF为关系数据库建模

本文小编为大家详细介绍“ASP.NET Core如何使用EF为关系数据库建模”,内容详细,步骤清晰,细节处理妥当,希望这篇“ASP.NET Core如何使用EF为关系数据库建模”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习
2023-06-29

Mysql 命令行模式访问操作mysql数据库操作

使用环境 在cmd模式下输入 mysql --version (查看mysql安装的版本). 完整的命令可以通过mysql --help来获取. 本测试使用的Mysql版本是mysql5, 本测试使用的SQL: db_yves.sql: 链
2022-05-27

调用pymysql模块操作数据库

1、创建数据库表: 1 def create_table(tb_name): 2 import pymysql#导入模块 3 #连接数据库 4 db = pymysql.Connect('localhost','ro
2023-01-31

数据库操作之PreparedStatement的使用

PreparedStatement的使用1.1 PreparedStatement介绍可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取 PreparedStatement 对象PreparedSt
数据库操作之PreparedStatement的使用
2014-11-23

python数据库操作--数据库使用概述

目录1. 数据库基础知识2. 访问数据库基本原理1.应用系统2.数据库驱动程序3.数据库系统3. ODBC与ADO1.** ODBC**2.ADO4. 关系型数据库总结1. 数据库基础知识 数据库(DB),可以长期存储在计算机内、有组织的、
2022-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录