.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. 流式布局(百分比布局) 概述: 流式布局…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
