.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. 流式布局(百分比布局) 概述: 流式布局…...
Qwen3视觉黑板报辅助数据库课程设计:ER图与数据关系可视化
Qwen3视觉黑板报辅助数据库课程设计:ER图与数据关系可视化 你是不是也经历过这样的场景?面对《数据库课程设计》这门课,老师布置了一个“图书管理系统”或者“学生选课系统”的题目,你脑子里有一堆想法,但就是不知道该…...
<数据集>yolo骑行者识别<目标检测>
数据集下载链接https://blog.csdn.net/qq_53332949/article/details/159770308?spm1011.2415.3001.5331数据集格式:VOCYOLO格式 图片数量:13674张 标注数量(xml文件个数):13674 标注数量(txt文件个数):13674 标注类别数&…...
开发者专属:OpenClaw调用Qwen3-14B完成API自动化测试
开发者专属:OpenClaw调用Qwen3-14B完成API自动化测试 1. 为什么选择OpenClaw做API测试自动化 去年接手一个金融数据平台项目时,我遇到了API测试的瓶颈——每次迭代需要手动执行200个Postman测试用例,还要人工核对返回结果。这种重复劳动不仅…...
百考通:AI精准赋能实践报告,让实习总结高效又专业
对于每一位在校学生和职场新人而言,实践报告都是记录成长、沉淀经验的关键载体,却也常常成为令人头疼的难题:要么不知如何梳理工作脉络,要么难以精准提炼收获与反思,要么在格式规范和字数要求上反复纠结。百考通&#…...
抖音视频批量下载终极指南:5分钟掌握免费去水印技巧
抖音视频批量下载终极指南:5分钟掌握免费去水印技巧 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…...
Native代码与Java的交互艺术——访问字段、调用方法
在 Android 开发、高性能计算或遗留系统整合中,Java 与 Native 代码(C/C)的交互(JNI)是不可或缺的技能。本文将以实战为导向,详细讲解如何在 Native 层访问 Java 对象字段、调用实例与静态方法、处理字符串…...
2026 靠谱网站建设公司推荐|中大型企业 / 上市公司建站避坑与优选指南
摘要 在 AI 与 GEO(生成式引擎优化)主导的 2026 年,企业官网早已不是简单的展示窗口,而是品牌信任、获客转化、合规披露、全球触达的核心数字资产。选择一家靠谱的网站建设公司,直接决定企业数字化成果与长期商业价值。…...
嵌入式开发关键技术演进与实战经验分享
1. 嵌入式开发的行业现状与核心挑战2023年的嵌入式开发领域呈现出明显的多元化发展趋势。作为一名从业超过十年的嵌入式工程师,我观察到这个行业正在经历从传统单机设备向智能化、网络化方向的快速转型。根据AspenCore最新发布的行业调查报告,目前超过30…...
MCP23009 I²C GPIO扩展芯片驱动设计与实战
1. MCP23009通用I/O扩展芯片驱动库深度解析与工程实践MCP23009是Microchip公司推出的8位IC总线可编程通用输入/输出(GPIO)扩展器,专为资源受限的嵌入式系统设计。该芯片通过标准IC接口(支持标准模式100 kHz和快速模式400 kHz&…...
基于Matlab的路面裂缝检测识别系统:实现精准路面“体检”
基于Matlab的路面裂缝检测识别系统设计,载入待识别图片,对目标图像进行直方图均衡化、中值滤波去噪、对比度增强、二值化处理、二值化滤波、裂缝识别、裂缝判断、裂分拼接、裂缝投影及标记等一系列操作,完成路面识别的准确识别 程序已调通&am…...
