.net 6.0 框架集成ef实战,步骤详解
一、代码框架搭建
搭建如下代码架构:
重点含EntityFrameworkCore工程,该工程中包含AppDbContext.cs和数据表实体AggregateObject
1、AppDbContext 代码案例
//AppDbContext 代码案例using Microsoft.EntityFrameworkCore;namespace EntityFrameworkCore
{public class AppDbContext : DbContext{public AppDbContext(DbContextOptions<AppDbContext> options) : base(options){}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);// 增加以下代码配置modelBuilder.ConfigDatabaseDescription();}public DbSet<CFUserAggregate> CFUserAggregate { get; set; } // 示例:User 是你的实体类// 添加其他 DbSet<T> 来表示其他数据表}}
2、实体案例
1)AggregateRootBase类:
存放表公共字段,例状态、创建时间等
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;namespace EntityFrameworkCore
{public abstract class AggregateRootBase{[Key] // 主键[StringLength(36)] // 字符串长度限制[DbDescription("主键ID")]public Guid? Id { get; set; }[StringLength(36)][DbDescription("创建人ID")]public Guid? CreateUserGuid { get; set; }[Required][DbDescription("创建时间")]public DateTime? CreateDateTime { get; set; }[StringLength(36)][DbDescription("修改人ID")]public Guid? ModifyUserGuid { get; set; }[DbDescription("修改时间")]public DateTime? ModifyDateTime { get; set; }}
}
2)CFUserAggregate 实体
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;namespace EntityFrameworkCore
{[Table("CF_User")][DbDescription("用户表")]public class CFUserAggregate : AggregateRootBase{[Required][StringLength(15)] // 字符串长度限制[DbDescription("登录人手机号码")]public string PhoneNumber { get; set; }[Required][StringLength(100)] // 字符串长度限制[DbDescription("登录密码")]public string Password { get; set; }[Required][StringLength(10)][DbDescription("状态: New:新增;Active:有效;InActive:无效/注销")]public string? RecordStatus { get; set; }}}
二、引入EF依赖
具体步骤:
三、配置数据库连接
appsettings.json文件中配置数据库访问链接
四、注册 AppDbContext 作为服务
具体代码:
#region 注册 AppDbContext 作为服务
// 添加数据库上下文服务
//builder.Services.AddDbContext<AppDbContext>(options =>
//{
// var connectionString = builder.Configuration.GetConnectionString("MySqlConnection");// options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
//});builder.Services.AddDbContext<AppDbContext>(optionsAction: x =>{x.UseMySql( builder.Configuration.GetConnectionString("MySqlConnection"), new MySqlServerVersion(new Version(8, 0, 23)));});
//这段代码是使用.NET Core(或.NET框架)中的依赖注入(Dependency Injection)功能。
//在这里,AddScoped 是指将服务注册为“作用域”生命周期,
//表示每次 HTTP 请求时都会创建一个新的实例,但在同一个请求内的所有地方都会共享同一个实例。
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
//builder.Services.AddScoped<RegisterServices>(); // 注册 YourService 类 参考案例
#endregion
五、将实体表更新到数据库中
在程序包管理器控制台执行下面的命令
//执行下面的命令生产待执行到数据库中的类文件
Add-Migration CF_User20240508//更新到数据库中
Update-Database
命令执行成功之后会产生相关类文件
命令执行成功之后会在数据库中产生对应表
六、在控制器中通过表实体访问数据库
七、拓展1:实体字段描述更新到数据库字段说明
1、将实体字段描述更新到数据库字段说明中,如下效果
SELECT COLUMN_NAME, COLUMN_COMMENT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = '数据库名称' AND TABLE_NAME = '表名';
2、具体实现步骤
1)DbDescriptionAttribute 类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EntityFrameworkCore
{//// 摘要:// 实体在数据库中的表和列的说明 在迁移的Up方法中调用(确保在所有表创建和修改完成后,避免找不到表和列)[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field, Inherited = true, AllowMultiple = false)]public class DbDescriptionAttribute : Attribute{//// 摘要:// 说明public virtual string Description{get;}//// 摘要:// 初始化新的实例//// 参数:// description:// 说明内容public DbDescriptionAttribute(string description){Description = description;}}
}
2)MigrationBuilderExtensions类:
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
using Microsoft.EntityFrameworkCore.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Microsoft.EntityFrameworkCore;namespace EntityFrameworkCore
{/// <summary>/// 表实体中表名、字段加字段说明/// </summary>public static class MigrationBuilderExtensions{public static void AddOrUpdateTableDescription(this MigrationBuilder migrationBuilder, string tableName, string description, string schema = "dbo"){if (!string.IsNullOrEmpty(description) && description.Contains('\'')){description = description.Replace("'", "''");}migrationBuilder.Sql("ALTER TABLE {tableName} COMMENT '{tableDescription}';".Replace("{tableDescription}", description).Replace("{schema}", schema).Replace("{tableName}", tableName));}public static void AddOrUpdateColumnDescription(this MigrationBuilder migrationBuilder, string tableName, string columnName, string columnType, bool isNullable, string description, string schema = "dbo"){Console.WriteLine(description);if (!string.IsNullOrEmpty(description) && description.Contains('\'')){description = description.Replace("'", "''");}migrationBuilder.Sql("ALTER TABLE {tableName} MODIFY COLUMN {columnName} {columnType} {isNullable} COMMENT '{columnDescription}';".Replace("{columnDescription}", description).Replace("{schema}", schema).Replace("{tableName}", tableName).Replace("{columnName}", columnName).Replace("{columnType}", columnType).Replace("{isNullable}", isNullable == true ? "" : " NOT NULL "));}public static MigrationBuilder ApplyDatabaseDescription(this MigrationBuilder migrationBuilder, Microsoft.EntityFrameworkCore.Migrations.Migration migration){string text = "dbo";string name = "DbDescription";foreach (var entityType in migration.TargetModel.GetEntityTypes()){string tableName = entityType.GetTableName();string schema = entityType.GetSchema();Console.WriteLine("tableName:" + tableName);Console.WriteLine("schema:" + schema);IAnnotation annotation = entityType.FindAnnotation(name);if (annotation != null){Console.WriteLine("annotation.Value:" + annotation.Value.ToString());migrationBuilder.AddOrUpdateTableDescription(tableName, annotation.Value.ToString(), string.IsNullOrEmpty(schema) ? text : schema);}foreach (var property in entityType.GetProperties()){IAnnotation annotation2 = property.FindAnnotation(name);if (annotation2 != null){migrationBuilder.AddOrUpdateColumnDescription(tableName, property.GetColumnName(), property.GetColumnType(), property.IsNullable, annotation2.Value.ToString(), string.IsNullOrEmpty(schema) ? text : schema);}}}return migrationBuilder;}}
}
3)ModelBuilderExtensions类:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;namespace EntityFrameworkCore
{public static class ModelBuilderExtensions{// 自定义方法,用于将描述信息应用到数据库中public static ModelBuilder ConfigDatabaseDescription(this ModelBuilder modelBuilder){foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes()){if (entityType.FindAnnotation("DbDescription") == null && (entityType.ClrType?.CustomAttributes.Any((CustomAttributeData attr) => attr.AttributeType == typeof(DbDescriptionAttribute)) ?? false)){entityType.AddAnnotation("DbDescription", (entityType.ClrType.GetCustomAttribute(typeof(DbDescriptionAttribute)) as DbDescriptionAttribute)?.Description);}foreach (IMutableProperty property in entityType.GetProperties()){if (property.FindAnnotation("DbDescription") != null || !(property.PropertyInfo?.CustomAttributes.Any((CustomAttributeData attr) => attr.AttributeType == typeof(DbDescriptionAttribute)) ?? false)){continue;}PropertyInfo propertyInfo = property.PropertyInfo;Type type = propertyInfo?.PropertyType;property.AddAnnotation("DbDescription", (propertyInfo.GetCustomAttribute(typeof(DbDescriptionAttribute)) as DbDescriptionAttribute)?.Description);}}return modelBuilder;}}}
4)在第5步执行完毕之后,在生成的文件中添加如下代码:
migrationBuilder.ApplyDatabaseDescription(this);
相关文章:

.net 6.0 框架集成ef实战,步骤详解
一、代码框架搭建 搭建如下代码架构: 重点含EntityFrameworkCore工程,该工程中包含AppDbContext.cs和数据表实体AggregateObject 1、AppDbContext 代码案例 //AppDbContext 代码案例using Microsoft.EntityFrameworkCore;namespace EntityFrameworkCo…...
[C/C++] -- 观察者模式
观察者模式是一种行为型设计模式,用于定义对象间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式涉及以下几个角色: 主题(Subject)&…...
秋招算法刷题8
20240422 2.两数相加 时间复杂度O(max(m,n)),空间复杂度O(1) public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode headnull,tailnull;int carry0;while(l1!null||l2!null){int n1l1!null?l1.val:0;int n2l2!…...
Docker使用方法
Docker是一种容器化平台,它可以帮助开发人员将应用程序和其依赖项打包成一个独立的、可移植的容器,以便在不同的环境中运行。 以下是使用Docker的基本步骤: 安装Docker:首先,您需要在您的机器上安装Docker。您可以从D…...

HTML学习|网页基本信息、网页基本标签、图像标签、超链接标签、列表标签、表格标签、媒体元素、页面结构分析、iframe内联框架
网页基本信息 DOCTYPE是设置使用什么规范,网页整个信息都在html标签中,head标签里包含字符集设置,网页介绍等信息,title标签是网页的名称,网页的主干都在body标签中 网页基本标签 标题标签 h1~h6都是标题标签&#x…...
001 websocket(评论功能demo)(消息推送)
文章目录 ReviewController.javaWebSocketConfig.javaWebSocketProcess.javaServletInitializer.javaWebsocketApplication.javareadmeindex.htmlapplication.yamlpom.xml ReviewController.java package com.example.controller;import com.example.websocket.WebSocketProces…...

二分查找向下取整导致的死循环69. x 的平方根
二分查找向下取整导致的死循环 考虑伪题目:从数组arr中查找出目标元素target对应的下标,如果数组中不存在目标元素,找 到第一个元素值小于target的元素的下标。 编写二分查找算法如下: Testvoid testBinarySearch(){int[] arr n…...
Kivy 异步任务
如果要进行一些非常耗时的操作(例如:爬虫等),那么页面就会在这里卡住,而系统就会以为这个软件无响应,并提示关闭,可以说明用户体验极差,因此我们在此处引入异步操作。 在py中引入事件调节器,并在…...
DEV--C++小游戏(吃星星(0.1))
目录 吃星星(0.1) 简介 头文件 命名空间变量 副函数 清屏函数 打印地图函数 移动函数 主函数 0.1版完整代码 吃星星(0.1) 注:版本<1为未实现或只实现部分 简介 用wasd去吃‘*’ 头文件 #include<bi…...

LINUX 入门 4
LINUX 入门 4 day6 7 20240429 20240504 耗时:240min 课程链接地址 第4章 LINUX环境编程——实现线程池 C基础 第3节 #define里面的行不能乱空行,要换行就打\ typedef 是 C 和 C 中的一个关键字,用于为已有的数据类型定义一个新的名字。…...

Imagine Flash、StyleMamba 、FlexControl、Multi-Scene T2V、TexControl
本文首发于公众号:机器感知 Imagine Flash、StyleMamba 、FlexControl、Multi-Scene T2V、TexControl You Only Cache Once: Decoder-Decoder Architectures for Language Models We introduce a decoder-decoder architecture, YOCO, for large language models, …...
Java Collections.emptyList() 方法详解
前言 在Java开发的日常中,我们常常需要处理集合数据结构,而这其中就免不了要面对“空集合”的场景。传统的做法可能是直接返回 null,但这往往会引入空指针异常的风险,降低了代码的健壮性。幸运的是,Java为我们提供了一…...

Vue前端环境准备
vue-cli Vue-cli是Vue官方提供的脚手架,用于快速生成一个Vue项目模板 提供功能: 统一的目录结构 本地调试 热部署 单元测试 集成打包上线 依赖环境:NodeJs 安装NodeJs与Vue-Cli 1、安装nodejs(已经安装就不用了) node-…...

代码随想录算法训练营第四十二天| 01背包问题(二维、一维)、416.分割等和子集
系列文章目录 目录 系列文章目录动态规划:01背包理论基础①二维数组②一维数组(滚动数组) 416. 分割等和子集①回溯法(超时)②动态规划(01背包)未剪枝版剪枝版 动态规划:01背包理论基…...

故障——蓝桥杯十三届2022国赛大学B组真题
问题分析 这道题纯数学,考察贝叶斯公式 AC_Code #include <bits/stdc.h> using namespace std; typedef pair<int,double> PI; bool cmp(PI a,PI b){if(a.second!b.second)return a.second>b.second;return a.first<b.first; } int main() {i…...
SSD存储基本知识
存储技术随着时间的推移经历了显著变化,新兴的存储介质正逐步挑战已经成为行业标准的硬盘驱动器(HDD)。在众多竞争者中,固态硬盘(SSD)是最广泛采用且最有潜力占据主导地位的——它们速度快、运行安静&#…...

buuctf-misc题目练习二
ningen 打开题目后是一张图片,放进winhex里面 发现PK,PK是压缩包ZIP 文件的文件头,下一步是想办法进行分离 Foremost可以依据文件内的文件头和文件尾对一个文件进行分离,或者识别当前的文件是什么文件。比如拓展名被删除、被附加…...

Nginx rewrite项目练习
Nginx rewrite练习 1、访问ip/xcz,返回400状态码,要求用rewrite匹配/xcz a、访问/xcz返回400 b、访问/hello时正常访问xcz.html页面server {listen 192.168.99.137:80;server_name 192.168.99.137;charset utf-8;root /var/www/html;location / {root …...
2024,AI手机“元年”? | 最新快讯
文 | 伯虎财经,作者 | 铁观音 2024年,小米、荣耀、vivo、一加、努比亚等品牌的AI手机新品如雨后春笋般涌现。因此,这一年也被业界广泛视为AI手机的“元年” 试想,当你轻触屏幕,你的手机不仅响应你的指令,更…...

5月9(信息差)
🌍 可再生能源发电量首次占全球电力供应的三成 🎄马斯克脑机接口公司 Neuralink 计划将 Link 功能扩展至现实世界,实现控制机械臂、轮椅等 马斯克脑机接口公司 Neuralink 计划将 Link 功能扩展至现实世界,实现控制机械臂、轮椅等…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...