.NET之生成数据库全流程

开篇语

本文主要是回顾下从项目创建到生成数据到数据库(代码优先)的全部过程。采用EFCore作为ORM框架。

本次示例环境:vs2019、net5、mysql

创建项目

本次事例代码是用过vs2019创建的ASP.NET Core Web API项目

可以通过可视化界面创建或者通过命令行创建

dotnet new webapi -o Net5ByDocker

创建实体类

安装连接MySQL数据库组件

    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.0" /><PackageReference Include="Pomelo.EntityFrameworkCore.MySql.Json.Newtonsoft" Version="5.0.0" />

增加实体类

    [Table("user")]public class User{public User(){Id = Guid.NewGuid().ToString();}public User(string account, string password, string creater) : this(){Account = account;Password = password;Deleted = false;SetCreater(creater);}[Key][Comment("主键")][StringLength(36)][Required]public string Id { get; private set; }[Comment("帐号")][StringLength(36)][Required]public string Account { get; private set; }[Comment("密码")][StringLength(36)][Required]public string Password { get; private set; }[Comment("余额")][Column(TypeName = "decimal(18, 2)")][Required]public decimal Money { get; set; }[Comment("是否删除")][Column(TypeName = "tinyint(1)")][Required]public bool Deleted { get; private set; }[Comment("创建人")][StringLength(20)][Required]public string Creater { get; private set; }[Comment("创建时间")][Required]public DateTime CreateTime { get; private set; }[Comment("修改人")][StringLength(20)][Required]public string Modifyer { get; private set; }[Comment("修改时间")][Required]public DateTime ModifyTime { get; private set; }public void SetCreater(string name){Creater = name;CreateTime = DateTime.Now;SetModifyer(name);}public void SetModifyer(string name){Modifyer = name;ModifyTime = DateTime.Now;}}

这种只是增加实体类类型的一种方式,可能这种看着比较乱,还可以通过OnModelCreating实现,详情看参考文档

增加数据库上下文OpenDbContext

    public class OpenDbContext : DbContext{public OpenDbContext(DbContextOptions<OpenDbContext> options): base(options){}public DbSet<User> Users { get; set; }}

Startup注入连接数据库操作

            var connection = Configuration["DbConfig:Mysql:ConnectionString"];var migrationsAssembly = IntrospectionExtensions.GetTypeInfo(typeof(Startup)).Assembly.GetName().Name;services.AddDbContext<OpenDbContext>(option => option.UseMySql(connection, ServerVersion.AutoDetect(connection), x =>{x.UseNewtonsoftJson();x.MigrationsAssembly(migrationsAssembly);}));

生成迁移文件

引用组件

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.5">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.5">

迁移命令

add-migration Init

结果

image.png

要看下生成的迁移文件是否是自己预期的那样子,也可以在这一步就生成数据库,命令:Update-Database

数据种子

增加OpenDbSend类,添加数据种子

    public class OpenDbSend{/// <summary>/// 生成数据库以及数据种子/// </summary>/// <param name="dbContext">数据库上下文</param>/// <param name="loggerFactory">日志</param>/// <param name="retry">重试次数</param>/// <returns></returns>public static async Task SeedAsync(OpenDbContext dbContext,ILoggerFactory loggerFactory,int? retry = 0){int retryForAvailability = retry.Value;try{dbContext.Database.Migrate();//如果当前数据库不存在按照当前 model 创建,如果存在则将数据库调整到和当前 model 匹配await InitializeAsync(dbContext).ConfigureAwait(false);//if (dbContext.Database.EnsureCreated())//如果当前数据库不存在按照当前 model创建,如果存在则不管了。//  await InitializeAsync(dbContext).ConfigureAwait(false);}catch (Exception ex){if (retryForAvailability < 3){retryForAvailability++;var log = loggerFactory.CreateLogger<OpenDbSend>();log.LogError(ex.Message);await SeedAsync(dbContext, loggerFactory, retryForAvailability).ConfigureAwait(false);}}}/// <summary>/// 初始化数据/// </summary>/// <param name="context"></param>/// <returns></returns>public static async Task InitializeAsync(OpenDbContext context){if (!context.Set<User>().Any()){await context.Set<User>().AddAsync(new User("azrng", "123456", "azrng")).ConfigureAwait(false);await context.Set<User>().AddAsync(new User("张三", "123456", "azrng")).ConfigureAwait(false);}await context.SaveChangesAsync().ConfigureAwait(false);}}

设置项目启动时候调用

        public static async Task Main(string[] args){var host = CreateHostBuilder(args).Build();using (var scope = host.Services.CreateScope()){var services = scope.ServiceProvider;var loggerFactory = services.GetRequiredService<ILoggerFactory>();var _logger = loggerFactory.CreateLogger<Program>();try{var openContext = services.GetRequiredService<OpenDbContext>();await OpenDbSend.SeedAsync(openContext, loggerFactory).ConfigureAwait(false);}catch (Exception ex){_logger.LogError(ex, $"项目启动出错  {ex.Message}");}}await host.RunAsync().ConfigureAwait(false);}

生成数据库

启动项目,自动生成数据库

image.png

表结构如下

image.png

如果后期数据库字段或者结构有变动,可以再次生成迁移文件然后生成数据库

查询数据

    /// <summary>/// 用户接口/// </summary>public interface IUserService{string GetName();/// <summary>/// 查询用户信息/// </summary>/// <param name="account"></param>/// <returns></returns>Task<User> GetDetailsAsync(string account);}/// <summary>/// 用户实现/// </summary>public class UserService : IUserService{private readonly OpenDbContext _dbContext;public UserService(OpenDbContext dbContext){_dbContext = dbContext;}public string GetName(){return "AZRNG";}///<inheritdoc cref="IUserService.GetDetailsAsync(string)"/>public async Task<User> GetDetailsAsync(string account){return await _dbContext.Set<User>().FirstOrDefaultAsync(t => t.Account == account).ConfigureAwait(false);}}

一般更推荐建立指定的返回Model类,然后只查询需要的内容,不直接返回实体类

控制器方法

        /// <summary>/// 查询用户详情/// </summary>/// <param name="account"></param>/// <returns></returns>[HttpGet]public async Task<ActionResult<User>> GetDetailsAsync(string account){return await _userService.GetDetailsAsync(account).ConfigureAwait(false);}

查询结果

{"id": "e8976d0a-6ee9-4e2e-b8d8-1fe6e85b727b","account": "azrng","password": "123456","money": 0,"deleted": false,"creater": "azrng","createTime": "2021-05-09T15:48:45.730302","modifyer": "azrng","modifyTime": "2021-05-09T15:48:45.730425"
}

参考文档

实体类型:https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-types?tabs=data-annotations

实体属性:https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-properties?tabs=data-annotations%2Cwithout-nrt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进军人工智能,数学基础很重要?

随着科技的快速发展&#xff0c;人工智能的重要性日渐显现。对于大多数新手来说&#xff0c;弄清楚入门人工智能需要哪些数学基础、需要熟悉什么框架等&#xff0c;都至关重要。机器学习是一个异常丰富的研究领域&#xff0c;有大量未解决的问题&#xff1a;公正、可解释性、易…

修改正文中参考文献标注_论文写作中怎样正确插入参考文献,引用文献如何标注?...

论文写作中怎样正确插入引文文献&#xff0c;引用文献如何标注&#xff1f;不管是大学毕业生还是期刊/评职称的我们在面对撰写论文时&#xff0c;参考文献的引用是必不可少的。参考文献的引用可以给论文增添很多的光彩。正确的在论文中引用参考问下你会在论文编写的同时省去很大…

.Net之多语言配置

开篇语首先非常感谢各位朋友或技术爱好者的关注。介绍支持多语言使网站可以覆盖更广泛的受众。ASP.NET Core 提供的服务和中间件可将网站本地化为不同的语言。本次示例环境&#xff1a;vs2019、net5配置无需引用Nuget包即可实现以下功能。注入容器services.AddLocalization(t &…

21张GIF动图让你秒懂数学原理

全世界有3.14 % 的人已经关注了数据与算法之美数学是很难的科学&#xff0c;但因为它是科学家用数学来解释宇宙的语言&#xff0c;我们无可避免的要学习它。看看下面的这些GIF动图&#xff0c;它们提供了视觉的方式来帮助你理解各种数学技巧。推荐阅读《12堂魔力数学课》。1.椭…

表格过滤器_记录和管理零散信息,什么软件比 Excel 表格更方便

SeaTable 的目标是帮助大家更好的组织和管理各种零散的信息&#xff0c;团队的请假信息就属于这样一类零散的信息。下面我们来看一下 &#xff0c;SeaTable 相比于 Excel 是如何更好的帮助我们来组织和管理这样的信息的。用 Excel 记录的团队请假信息下面两张表是比较常见的请假…

使用 Source Generator 代替 T4 动态生成代码

使用 Source Generator 代替 T4 动态生成代码Intro在 Source Generator 出现之前有一些重复性的代码&#xff0c;我会使用 T4 去生成&#xff0c;这样就可以一定程度上避免复制粘贴和可维护性也会更好一些。在了解了一些 Source Generator 之后&#xff0c;就想尝试把现在项目里…

资料分享 | 数据挖掘实例资料分享来袭

小编从大学开始&#xff0c;便开启资料收集功能。随着大数据时代的来临&#xff0c;计算机发展进入新的阶段&#xff0c;再加上日常的深入研究&#xff0c;小编收集整理了丰富的数据挖掘资料&#xff0c;内容涵盖“程序”&#xff0c;“数据”、“文档”等。这次小编再次把所有…

修改图层的范围_【PS|第39期】数字绘画 使用填充图层

惟有悲观净化而成的乐观&#xff0c;才是真正的乐观。——尼采)填充图层是一种只承载纯色、渐变和图案的特殊图层&#xff0c;其特点是填充内容可以修改。另外&#xff0c;设置成不同的混合模式和不透明度后&#xff0c;可用于修改其他图层的颜色或生成图像混合效果。填充图层都…

我的注释那去了?

当我们用nuget引用三方库时&#xff0c;在类型&#xff0c;或类型成员上会有注释&#xff0c;如下图&#xff0c;是MySql官方包&#xff0c;command的ExecuteNonQuery的注释我们自己写一个类库项目CommentsLibrary&#xff0c;给类&#xff0c;构造函数&#xff0c;方法添加xml…

[原] jQuery EasyUI 1.2.6源码、Demo合集、离线API

下载地址&#xff1a; http://files.cnblogs.com/purediy/jquery-easyui-1.2.6.zip 兄弟版本&#xff1a; jQuery EasyUI 1.3.4 离线API、Demo jQuery EasyUI 1.3.2 离线API、Demo jQuery EasyUI 1.3.0 Demo合集、离线API、动态换肤 相信关注过jQuery UI 的大部分都查到过easyu…

看书的一点小建议!

阅读本文大概需要6分钟。昨天看见小北写了一篇&#xff1a;「看书的一点小建议」&#xff0c;写的很不错&#xff0c;今天也分享一下自己看书的心得。其实不少读者问过我怎么看计算机经典大厚书、怎么看产品运营经典大厚书、怎么提高看书效率&#xff1a;电影教父里有台词&…

技巧:Excel用得好,天天没烦恼

全世界有3.14 % 的人已经关注了数据与算法之美Excel是Office三大神器当中最神秘、但也是最能提高你效率的工具了。而我们中的太多小伙伴&#xff0c;却一直把它当做是个“电子表格工具”。今天一起涨姿势&#xff0c;学会下面这些神技&#xff0c;你的Excel分分钟超过90%的同事…

操作数数据类型 char 对于 sum 运算符无效。_数据类型和运算符

数据类型和运算符1.进制1.1文件存储单位​ 任何数据在计算机中都是以二进制的形式存在的&#xff0c;二进制早期由电信号开关演变而来 。​ 一个电信号或者一个二进制位统称为Bit位&#xff0c;8个Bit位为一组组成一个字节Byte 。​ 一个bit位表示的数的范围&#xff1a;0和1​…

我所理解的开源软件供应链安全

点击上方“开源社”关注我们| 作者&#xff1a;庄表伟| 编辑&#xff1a;钱英宇| 设计&#xff1a;谭嘉露| 责编&#xff1a;王玥敏1供应链与断供隐喻会帮助人&#xff0c;也会误导人。当我们谈到“供应链”时&#xff0c;会产生哪些联想&#xff1f;环环相扣&#xff1f;缺一不…

82 个代码案例实践,带你学好 Python 机器学习

全世界有3.14 % 的人已经关注了数据与算法之美如果村里通了网&#xff0c;那你一定知道【AI】人工智能。如果你会网上冲浪&#xff0c;那你一定看到过【ML】机器学习。小编在网上看到一个段子&#xff1a;ML派坐落美利坚合众山中&#xff0c;百年来武学奇才辈出&#xff0c;隐然…

查询程序崩溃日志_PC 崩溃报告途径 amp; 临时解决方法

TC Sera (社区经理)&#xff1a;你好&#xff01;如果您在电脑游戏中遇到与 Nvidia 驱动程序相关的崩溃情况&#xff0c;请打开视频设置(Video Settings)中的诊断模式(Diagnostics Mode)并重新启动游戏。如果您遇到问题&#xff0c;请打包&#xff1a;%localappdata%\Gears5\Sa…

C# ConcurrentBag的实现原理

一、前言笔者最近在做一个项目&#xff0c;项目中为了提升吞吐量&#xff0c;使用了消息队列&#xff0c;中间实现了生产消费模式&#xff0c;在生产消费者模式中需要有一个集合&#xff0c;来存储生产者所生产的物品&#xff0c;笔者使用了最常见的List<T>集合类型。由于…

Linux里10个最危险的命令

全世界只有3.14 % 的人关注了数据与算法之美Linux命令行佷有用、很高效&#xff0c;也很有趣&#xff0c;但有时候也很危险&#xff0c;尤其是在你不确定你自己在正在做什么时候。推荐阅读Linux之父林纳斯自传《只是为了好玩》这篇文章将会向你介绍十条命令&#xff0c;但你最好…

让你立刻爱上数学的10个算术游戏

全世界只有3.14 % 的人关注了数据与算法之美死理性派的小编经常会被问到的一个问题&#xff1a;数学到底哪里有趣了&#xff0c;数学之美又在哪里&#xff1f;这篇文章精心选择了 10 个老少咸宜的算术问题&#xff0c;以定理、趣题甚至未解之谜等各种形式带领大家窥探数学世界的…

iPhone 的 Push(推送通知)功能原理浅析

第一部分&#xff1a;Push原理(以下绝大多数内容参考自、图片来自iPhone OS Reference Library)机制简介Push 的工作机制可以简单的概括为下图图中&#xff0c;Provider是指某个iPhone软件的Push服务器。 APNS 是Apple Push Notification Service&#xff08;Apple Push服务器&…