.Net C# 基于EFCore的DBFirst和CodeFirst
DBFirst和CodeFirst
1 概念介绍
1.1 DBFirst(数据库优先)
- 含义:这种模式是先创建数据库架构,包括表、视图、存储过程等数据库对象。然后通过实体框架(Entity Framework)等工具,根据已有的数据库结构来生成对应的实体类和数据访问代码。
- 应用场景:当已经存在一个成熟的数据库,例如从旧系统迁移过来的数据库,或者数据库由专业的数据库管理员设计好,开发人员需要基于这个数据库来构建应用程序时,DBFirst 是一个很好的选择。
1.2 CodeFirst(代码优先)
- 含义:开发人员首先通过编写代码来定义实体类及其之间的关系,如在 C# 中使用实体框架的 CodeFirst 模式。然后,根据这些代码中的定义,实体框架可以自动创建数据库架构或者更新已有的数据库架构来匹配代码中的实体定义。
- 应用场景:在新项目的开发初期,尤其是团队中有熟练的开发人员能够很好地设计领域模型时,CodeFirst 可以让开发人员专注于业务逻辑和实体关系的构建,而不用担心数据库的细节。它非常适合敏捷开发环境,能够快速迭代数据库架构和应用程序代码。
2 工作流程对比
2.1 DBFirst 工作流程
- 数据库设计:数据库管理员(DBA)或者熟悉数据库设计的人员使用数据库管理工具(如 SQL Server Management Studio 等)创建数据库,包括表结构、数据类型、约束条件等。
- 生成代码:在 Visual Studio 等开发工具中,使用实体框架的 “从数据库生成模型” 功能,根据数据库结构生成实体类和数据访问上下文(DbContext)类。这些生成的类可以作为数据访问层的基础,开发人员可以在其上添加业务逻辑。
- 数据访问和业务逻辑:开发人员在生成的代码基础上,编写业务逻辑方法,如查询、插入、更新和删除数据等操作,将数据访问和业务逻辑结合起来,实现应用程序的功能。
2.2 CodeFirst 工作流程
- 实体类定义:开发人员在代码中定义实体类,包括属性、数据类型和实体之间的关系(如一对多、多对多等)。例如,在 C# 中使用实体框架时,通过使用System.ComponentModel.DataAnnotations命名空间中的特性(如[Key]用于定义主键,[Required]用于定义必填字段等)来装饰实体类的属性。
- 数据库上下文定义:创建一个继承自DbContext的类,在这个类中定义DbSet属性,用于表示数据库中的表。例如,public DbSet Customers { get; set; }表示一个名为Customers的表,其对应的实体类是Customer。
- 数据库迁移(可选但推荐):使用实体框架的迁移功能(如Enable - Migrations和Add - Migration命令)来创建和管理数据库架构的变更。在应用程序启动时,通过调用Database.SetInitializer方法或者在配置文件中设置数据库初始化策略,实体框架可以根据实体类的定义自动创建或者更新数据库。
- 数据访问和业务逻辑:与 DBFirst 类似,开发人员在定义好的实体类和数据库上下文基础上,编写业务逻辑方法来实现应用程序的功能。
3 优缺点对比
3.1 DBFirst 优缺点
- 优点:
- 对于已有的复杂数据库,能够快速生成对应的代码,节省了大量的实体类和数据访问代码的编写时间。
- 数据库架构已经确定,开发人员只需要关注应用程序如何使用数据库中的数据,适合数据库结构相对稳定的项目。
- 缺点:
- 如果数据库结构发生变化,需要重新生成代码,可能会导致之前对生成代码的修改丢失,需要重新进行合并和调整。
- 开发人员对数据库结构的依赖较强,在代码中对数据库的更改可能不够灵活,需要在数据库和代码之间频繁切换来进行修改。
3.2 CodeFirst 优缺点
- 优点:
- 开发人员可以完全通过代码来控制数据库架构,使得领域模型和代码之间的一致性更好。
- 便于进行敏捷开发和迭代,当业务需求发生变化时,可以直接在代码中修改实体类的定义,然后通过迁移来更新数据库架构。
- 缺点:
- 对于大型的、已有的数据库迁移到 CodeFirst 模式可能比较复杂,需要花费更多的时间来重新设计和实现实体类以及数据访问逻辑。
- 开发人员需要对实体框架的 CodeFirst 相关知识有深入的了解,如数据库迁移策略、数据注释和流畅 API 等,否则可能会导致数据库架构不符合预期或者出现数据丢失等问题。
4 CoreFirst 示例
4.1 环境搭建
- 创建项目
- 创建一个新的.NET 项目(如控制台应用程序或ASP.NET Core Web API 等)。
- 安装必要的 NuGet 包
- 安装Npgsql.EntityFrameworkCore.PostgreSQL包。这个包允许你在 Entity Framework Core 中使用 PostgreSQL 数据库。可以通过在项目目录下的命令行中执行dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL来安装。
4.2 定义实体类
-
Blog 类
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace BloggingApp {[Table("blogs")]public class Blog{[Key]public int BlogId { get; set; }[Required][StringLength(100)]public string Name { get; set; }public DateTime CreatedDate { get; set; } = DateTime.Now;public IList<Post> Posts { get; set; } = new List<Post>();} }
- 解释:
[Table("blogs")]
指定实体类对应的数据库表名为blogs
。[Key]
定义BlogId
为表的主键。[Required]
和[StringLength(100)]
用于验证Name
属性,确保其为必填且长度不超过 100。CreatedDate
默认为当前日期时间,表示博客的创建时间。Posts
是一个IList<Post>
类型的属性,表示一篇博客可以有多篇文章(Post
)与之关联。
- 解释:
-
Post 类
[Table("posts")] public class Post {[Key]public int PostId { get; set; }[Required][StringLength(200)]public string Title { get; set; }public string Content { get; set; }public DateTime PublishedDate { get; set; } = DateTime.Now;public int BlogId { get; set; }[ForeignKey("BlogId")]public Blog Blog { get; set; }public IList<Comment> Comments { get; set; } = new List<Comment>(); }
- 解释:
[Table("posts")]
表示对应的数据库表是posts
。[Key]
定义PostId
为主键。Title
是文章标题,Content
是文章内容,PublishedDate
默认为当前时间,表示发布日期。BlogId
是外键,通过[ForeignKey("BlogId")]
特性关联到Blog
类的BlogId
,Blog
属性表示这篇文章所属的博客。Comments
是一个IList<Comment>
类型的属性,表示一篇文章可以有多个评论(Comment
)。
- 解释:
-
Comment 类
[Table("comments")] public class Comment {[Key]public int CommentId { get; set; }[Required]public string Content { get; set; }public DateTime CommentedDate { get; set; } = DateTime.Now;public int PostId { get; set; }[ForeignKey("PostId")]public Post Post { get; set; } }
- 解释:
[Table("comments")]
表示对应的数据库表是comments
。[Key]
定义CommentId
为主键。Content
是评论内容,CommentedDate
默认为当前时间,表示评论日期。PostId
是外键,通过[ForeignKey("PostId")]
特性关联到Post
类的PostId
,Post
属性表示这个评论所属的文章。
- 解释:
4.3 创建数据库上下文类
using Microsoft.EntityFrameworkCore;
namespace BloggingApp
{public class BloggingContext : DbContext{public BloggingContext(DbContextOptions<BloggingContext> options) : base(options){}public DbSet<Blog> Blogs { get; set; }public DbSet<Post> Posts { get; set; }public DbSet<Comment> Comments { get; set; }}
}
- 解释:
- 构造函数接受DbContextOptions<BloggingContext>
类型的参数,并传递给基类DbContext
的构造函数。
-DbSet<Blog> Blogs
、DbSet<Post> Posts
和DbSet<Comment> Comments
分别定义了对应数据库表的属性,用于操作blogs
、posts
和comments
表。
4.4 配置数据库连接字符串
- 在
appsettings.json
文件中添加以下内容:
{"ConnectionStrings": {"BloggingDbConnection": "Host=localhost;Database=blogging_app;Username=postgres;Password=your_password"}
}
-
注意:
- 你需要将
your_password
替换为你实际的 PostgreSQL 数据库密码。 Host
是数据库服务器地址,Database
是数据库名称,Username
是登录用户名。
- 你需要将
-
在
Program.cs
(如果是控制台应用程序)或Startup.cs
(如果是ASP.NET Core 应用程序)中读取连接字符串并配置数据库上下文:- 对于控制台应用程序,在
Program.cs
中:
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System.IO; class Program {static void Main(){var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);IConfigurationRoot configuration = builder.Build();var connectionString = configuration.GetConnectionString("BloggingDbConnection");var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>().UseNpgsql(connectionString);using (var context = new BloggingContext(optionsBuilder.Options)){// 在这里可以进行数据库操作,如插入、查询等}} }
- 对于ASP.NET Core 应用程序,在
Startup.cs
中:
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; public class Startup {public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }public void ConfigureServices(ServiceCollection services){var connectionString = Configuration.GetConnectionString("BloggingDbConnection");services.AddDbContext<BloggingContext>(options =>options.UseNpgsql(connectionString));// 其他服务配置}// 其他方法 }
- 对于控制台应用程序,在
4.5 数据库迁移和操作
-
安装EF工具
- 安装全局工具
dotnet tool install --global dotnet-ef
- 更新工具
dotnet tool update --global dotnet-ef
- 安装全局工具
-
添加迁移(假设是初始创建)
- 在命令行中执行
dotnet ef migrations add InitialCreate
。
- 在命令行中执行
-
更新数据库
- 在命令行中执行
dotnet ef database update
。
- 在命令行中执行
-
数据库操作示例 - 插入数据
- 在
using
块中(对于控制台应用程序)或在服务方法中(对于ASP.NET Core 应用程序)插入数据:
using (var context = new BloggingContext(optionsBuilder.Options)) {var blog = new Blog{Name = "My Awesome Blog"};var post = new Post{Title = "First Post",Content = "This is the content of my first post.",Blog = blog};var comment = new Comment{Content = "Great post!",Post = post};context.Blogs.Add(blog);context.Posts.Add(post);context.Comments.Add(comment);context.SaveChanges(); }
- 在
-
解释:
- 首先创建一个
Blog
对象,然后创建一个Post
对象并关联到前面的Blog
,接着创建一个Comment
对象并关联到Post
。 - 通过
context.Blogs.Add
、context.Posts.Add
和context.Comments.Add
将这些对象添加到相应的数据库表中。 - 最后,通过
context.SaveChanges
将更改保存到数据库。
- 首先创建一个
5 DBFirst 示例
5.1 生成数据库上下文和实体类
- 打开命令行工具,执行
dotnet ef dbcontext scaffold "Host=localhost;Port=5432;Database=your_database_name;Username=postgres;Password=your_password" Npgsql.EntityFrameworkCore.PostgreSQL -o Models
。- 解释:
- 这个命令根据指定的 PostgreSQL 数据库连接字符串和提供程序(
Npgsql.EntityFrameworkCore.PostgreSQL
)来生成数据库上下文和实体类,并输出到Models
文件夹下。
- 这个命令根据指定的 PostgreSQL 数据库连接字符串和提供程序(
- 解释:
相关文章:

.Net C# 基于EFCore的DBFirst和CodeFirst
DBFirst和CodeFirst 1 概念介绍 1.1 DBFirst(数据库优先) 含义:这种模式是先创建数据库架构,包括表、视图、存储过程等数据库对象。然后通过实体框架(Entity Framework)等工具,根据已有的数据…...

w012基于springboot的社区团购系统设计
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...

笔记本降频超鬼锁屏0.39电脑卡到不行解决办法实操记录
1、最开始没发现cpu问题,我发现我电脑突然异常的卡顿,最开始我怀疑是不是微软win用久了或者自动更新导致的问题,于是自己重装了操作系统 发现问题依然存在 2、我怀疑难道我的 cpu 内存 固态硬盘 其中一个有点问题?心想要是硬盘的…...

优选算法第四讲:前缀和模块
优选算法第四讲:前缀和模块 1.[模板]前缀和2.【模板】二维前缀和3.寻找数组的中心下标4.除自身以外数组的乘积5.和为k的子数组6.和可被k整除的子数组7.连续数组8.矩阵区域和 1.[模板]前缀和 链接: link #include <iostream> #include <vector> using…...

ubuntu20.04 加固方案-设置限制su命令用户组
一、编辑/etc/pam.d/su配置文件 打开终端。 使用文本编辑器(如vim)编辑/etc/pam.d/su文件。 vim /etc/pam.d/su 二、添加配置参数 在打开的配置文件的中,添加以下参数: auth required pam_wheel.so 创建 wheel 组 并添加用户 …...

TDengine数据备份与恢复
TDengine数据备份与恢复 一、数据备份和恢复介绍二、基于 taosdump 进行数据备份恢复三、基于 taosExplorer 进行数据备份恢复3.1 taosExplorer 的安装与配置3.2 使用taosExplorer 进行数据备份 一、数据备份和恢复介绍 官网地址:TDengine - 数据备份和恢复 为了防止…...

2024最新的开源博客系统:vue3.x+SpringBoot 3.x 前后端分离
本文转载自:https://fangcaicoding.cn/article/54 大家好!我是方才,目前是8人后端研发团队的负责人,拥有6年后端经验&3年团队管理经验,截止目前面试过近200位候选人,主导过单表上10亿、累计上100亿数据…...

研究中的“异质性”、“异质性结果”是指?
“异质性”这个词在统计学和研究中指的是数据、现象或群体之间的差异,即不同个体、组别、区域或时间点的表现或特征并不相同。相对的概念是“同质性”,即所有个体或组别在某一方面表现相同或接近。 异质性(Heterogeneity)的含义 …...

Springboot整合AOP和redis
aop pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency> 开启自动代理 注意:在完成了引入AOP依赖包后,一般来说并不需要去做其他…...

freetype学习总结
freetype学习总结 目录 freetype学习总结1. LCD显示字符问题引入2. freetype概念2.1 嵌入式设备使用FreeType的方法步骤2.2 嵌入式设备使用FreeType的注意事项 3. freetype官方C示例3.1 example1.c源码 4. 嵌入式设备上使用FreeType的简单示例4.1 简单示例代码4.2 代码分析 5. …...

上海亚商投顾:沪指缩量调整 华为概念股午后爆发
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 市场全天震荡调整,沪指、深成指午后跌超1%,创业板指一度跌逾2%,尾盘跌幅有…...

操作系统与进程【单身狗定制版】
大家好呀 我是浪前 今天给大家讲解的是操作系统与进程 祝愿所有点赞关注的人,身体健康,一夜暴富,升职加薪迎娶白富美!!! 点我领取迎娶白富美大礼包 前言: 我们今天我们来学习操作系统 当然啦,操作系统是一个很庞大的…...

监听el-table中 自定义封装的某个组件的值发现改变调用函数
监听el-table中 自定义封装的某个组件的值发现改变调用函数 当你在一个 el-table 中使用封装的自定义组件作为单元格内容时,监听这个组件的值变化并调用函数,可以通过以下步骤实现: 创建自定义组件:首先创建一个自定义的 Vue 组…...

frida安装
开始安装 frida https://github.com/frida/frida/releases 下载安装的时候查看自己手机是多少位的 adb shell getprop ro.product.cpu.abi # 按照自己的机型下载进行解压里面有个文件放入到手机中开始进入手机 然后按照下面的图执行命令 其中log 我只是看了下 不需要执行因为刚…...

链表详解(三)
目录 链表功能实现链表的查找SLNode* SLFind(SLNode* phead, SLNDataType x)代码 链表任意位置前插入void SLInsert(SLNode**pphead,SLNode* pos, SLNDataType x)代码 链表任意位置前删除void SLErase(SLNode**pphead,SLNode* pos)代码 链表任意位置后插…...

【RESP问题】RESP.app GUI for Redis 连接不上redis服务器
问题描述: 在使用RESP的时候出现地址和密码正确但是连接不上Redis服务器的情况,但是由于在之前我是修改过Redis的配置文件的,所以现在怀疑是防火墙的问题。 问题解决: 在[rootlocalhost ~]下输入以下命令打开防火墙 #放通6379/…...

【github 有趣项目】AMULE
官方网站github ‘All-platform’ P2P client based on eMule电骡社区文档 下载&安装 去官方网站下载(社区版一般版本较新),解压版解压打开即可。 点击“下一页”,输入名称,后边全都下一步即可 通过upnp设置端…...

【WRF数据准备】土地利用类型分类标准:USGS+MODIS IGBP 21
【WRF数据准备】土地利用类型分类标准:USGSMODIS IGBP 21 WRF常用土地类型分类MODIS IGBP 21USGSNLCD Landuse 选择土地利用分类标准替换城市土地类型后更改土地利用分类参考 WRF常用土地类型分类 WRF中土地利用类型最高分辨率是30s,且主要分为MODIS和U…...

KVM虚拟机迁移:无缝迁徙,重塑云上未来
作者简介:我是团团儿,是一名专注于云计算领域的专业创作者,感谢大家的关注 座右铭: 云端筑梦,数据为翼,探索无限可能,引领云计算新纪元 个人主页:团儿.-CSDN博客 目录 前言&#…...

CSS常见适配布局方式
在网页设计中,布局是确保内容按预期显示的关键部分。CSS 提供了多种布局方式,每种方式都有其特定的用途和优势。以下是您提到的五种布局方式的详细解释: 1. 流式布局(百分比布局) 概述: 流式布局…...

ArkUI常用布局:构建响应式和高效的用户界面
在HarmonyOS应用开发中,ArkUI作为用户界面开发框架,提供了多种布局方式来帮助开发者构建响应式和高效的用户界面。本文将详细介绍ArkUI中的常用布局方式,包括线性布局、层叠布局、弹性布局、相对布局、栅格布局、列表和轮播布局,并…...

论面向服务架构设计及其应用
一、引言 企业应用集成(Enterprise Application Integration,EAI)是企业实现信息系统协同工作的关键途径,尤其是在当前多系统、多平台并存的企业环境下,集成需求愈发显著。面向服务架构(Service-Oriented …...

HTML5 + CSS3 + JavaScript 编程语言学习教程
HTML5 CSS3 JavaScript 编程语言学习教程 欢迎来到这篇关于 HTML5、CSS3 和 JavaScript 的详细学习教程!无论你是初学者还是有一定基础的开发者,这篇文章都将帮助你深入理解这三种技术的核心概念、语法和应用。 目录 HTML5 1.1 HTML5 简介1.2 HTML5 …...

Java日志脱敏——基于logback MessageConverter实现
背景简介 日志脱敏 是常见的安全需求,最近公司也需要将这一块内容进行推进。看了一圈网上的案例,很少有既轻量又好用的轮子可以让我直接使用。我一直是反对过度设计的,而同样我认为轮子就应该是可以让人拿去直接用的。所以我准备分享两篇博客…...

在 Ubuntu 22.04 上部署Apache 服务, 访问一张照片
要在 Ubuntu 22.04 上部署一张照片,使其可以通过 Apache 访问,你可以按照以下步骤进行操作: 1. 安装 Apache(如果尚未安装) 如果你还没有安装 Apache,可以使用以下命令: sudo apt update sud…...

从0学习React(10)
示例代码: const columns: ProColumns<API.BasicInfoItem>[] [{title: 设备编码,dataIndex: deviceCode,ellipsis: true,width: 40,},{title: 设备名称,dataIndex: deviceName,ellipsis: true,width: 50,},{title: 产线-工序,dataIndex: deviceClassifyName…...

Redis-结构化value对象的类型
文章目录 一、Redis的结构化value对象类型的介绍二、Redis的这些结构化value对象类型的通用操作查看指定key的数据类型查看所有的key判断指定key是否存在为已存在的key进行重命名为指定key设置存活时间pexpire与expire 查看指定Key的存活时间为指定key设置成永久存活 三、Redis…...

【QT】Qt对话框
个人主页~ Qt窗口属性~ Qt窗口 五、对话框2、Qt内置对话框(1)Message Box(2)QColorDialog(3)QFileDialog(4)QFontDialog(5)QInputDialog 五、对话框 2、Qt内…...

【计算机网络篇】数据链路层(14)虚拟局域网VLAN(概述,实现机制)
文章目录 🛸虚拟局域网VLAN🍔虚拟局域网VLAN的实现机制🥚IEEE 802.1Q帧🥚以太网交换机的接口类型🗒️例一:在一个交换机上不进行人为的VLAN划分,交换机各接口默认属于VLAN1且类型为Access的情况…...

伺服中的电子凸轮与追剪
一、机械凸轮 机械凸轮是一个具有曲线轮廓或凹槽的构件,它把运动特性传递给紧靠其边缘移动的推杆,推杆又带动机架做周期性运动。 凸轮的推杆位置跟随凸轮角度的周期性变化而变化,其运动特性与机械凸轮的外形相关,定义凸轮…...