.NET之生成数据库全流程实现

 更新时间:2021年9月22日 09:59  点击:1297

开篇语

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

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

创建项目

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

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

dotnet new webapi -o Net5ByDocker

创建实体类

安装组件

    <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

结果

要看下生成的迁移文件是否是自己预期的那样子,也可以在这一步就生成数据库,命令: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);
        }

生成数据库

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

表结构如下

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

查询数据

    /// <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

到此这篇关于.NET之生成数据库全流程实现的文章就介绍到这了,更多相关.NET 生成数据库内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • PHP 数据库缓存Memcache操作类

    操作类就是把一些常用的一系列的数据库或相关操作写在一个类中,这样调用时我们只要调用类文件,如果要执行相关操作就直接调用类文件中的方法函数就可以实现了,下面整理了...2016-11-25
  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • Intellij IDEA连接Navicat数据库的方法

    这篇文章主要介绍了Intellij IDEA连接Navicat数据库的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借价值,需要的朋友可以参考下...2021-03-25
  • 在数据库里将毫秒转换成date格式的方法

    在开发过程中,我们经常会将日期时间的毫秒数存放到数据库,但是它对应的时间看起来就十分不方便,我们可以使用一些函数将毫秒转换成date格式。 一、 在MySQL中,有内置的函数from_unixtime()来做相应的转换,使用如下: 复制...2014-05-31
  • .NET Core下使用Kafka的方法步骤

    这篇文章主要介绍了.NET Core下使用Kafka的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • C#操作本地文件及保存文件到数据库的基本方法总结

    C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
  • 如何解决局域网内mysql数据库连接慢

    通过内网连另外一台机器的mysql服务, 确发现速度N慢! 等了大约几十秒才等到提示输入密码。 但是ping mysql所在服务器却很快! 想到很久之前有过类似的经验, telnet等一些服务在连接请求的时候,会做一些反向域名解析(如果...2015-10-21
  • MySQL快速复制数据库数据表的方法

    某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库。使用以下方法,可以非常简单地实现。假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb。步骤如下:1. 首先创建新的数据库newd...2015-10-21
  • mysqldump命令导入导出数据库方法与实例汇总

    mysqldump命令的用法1、导出所有库系统命令行mysqldump -uusername -ppassword --all-databases > all.sql 2、导入所有库mysql命令行mysql>source all.sql; 3、导出某些库系统命令行mysqldump -uusername -ppassword...2015-10-21
  • Win10 IIS 安装.net 4.5的方法

    这篇文章主要介绍了Win10 IIS 安装及.net 4.5及Win10安装IIS并配置ASP.NET 4.0的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • Mysql数据库错误代码中文详细说明

    1005:创建表失败1006:创建数据库失败1007:数据库已存在,创建数据库失败1008:数据库不存在,删除数据库失败1009:不能删除数据库文件导致删除数据库失败1010:不能删除数据目录导致删除数据库失败1011:删除数据库...2013-09-23
  • php二维码生成

    本文介绍两种使用 php 生成二维码的方法。 (1)利用google生成二维码的开放接口,代码如下: /** * google api 二维码生成【QRcode可以存储最多4296个字母数字类型的任意文本,具体可以查看二维码数据格式】 * @param strin...2015-10-21
  • Java生成随机姓名、性别和年龄的实现示例

    这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
  • 详解.NET Core 3.0 里新的JSON API

    这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • c#异步读取数据库与异步更新ui的代码实现

    这篇文章主要介绍了c#从数据库里取得数据并异步更新ui的方法,大家参考使用吧...2020-06-25
  • C#生成随机数功能示例

    这篇文章主要介绍了C#生成随机数功能,涉及C#数学运算与字符串操作相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • Yii2.0高级框架数据库增删改查的一些操作

    yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2使用中的一些基本的增删改查操作。 User::find()->all(); //返回所有用户数据; User::findOne($id); //返回 主键...2015-11-24