博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET之生成数据库全流程
阅读量:3523 次
发布时间:2019-05-20

本文共 6997 字,大约阅读时间需要 23 分钟。

目录


 

开篇语

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

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

创建项目

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

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

dotnet new webapi -o Net5ByDocker

创建实体类

安装连接MySQL数据库组件

    
    

增加实体类

    [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
 options)            : base(options)        {        }        public DbSet
 Users { get; set; }    }

Startup注入连接数据库操作

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

生成迁移文件

引用组件

迁移命令

add-migration Init

结果

图片

image.png

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

数据种子

增加OpenDbSend类,添加数据种子

    public class OpenDbSend    {        ///         /// 生成数据库以及数据种子        ///         /// 
数据库上下文        /// 
日志        /// 
重试次数        /// 
        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
();                    log.LogError(ex.Message);                    await SeedAsync(dbContext, loggerFactory, retryForAvailability).ConfigureAwait(false);                }            }        }        /// 
        /// 初始化数据        ///         /// 
        /// 
        public static async Task InitializeAsync(OpenDbContext context)        {            if (!context.Set
().Any())            {                await context.Set
().AddAsync(new User("azrng", "123456", "azrng")).ConfigureAwait(false);                await context.Set
().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
();                var _logger = loggerFactory.CreateLogger
();                try                {                    var openContext = services.GetRequiredService
();                    await OpenDbSend.SeedAsync(openContext, loggerFactory).ConfigureAwait(false);                }                catch (Exception ex)                {                    _logger.LogError(ex, $"项目启动出错  {ex.Message}");                }            }            await host.RunAsync().ConfigureAwait(false);        }

生成数据库

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

图片

image.png

表结构如下

图片

image.png

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

查询数据

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

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

控制器方法

        ///         /// 查询用户详情        ///         /// 
        /// 
        [HttpGet]        public async Task
> 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://gmwhj.baihongyu.com/

你可能感兴趣的文章
数据库基础技巧及用法
查看>>
实用方法:无request参数时获得当前的request的方法
查看>>
JS操作数组常用实用方法
查看>>
java实现MD5多次进行加密加盐操作
查看>>
springboot实现CAS的server服务器端的搭建,并实现链接mysql数据库,自定义加密算法
查看>>
Python超详细的安装教程
查看>>
小甲鱼Python第一讲(我和Python的第一次亲密接触)
查看>>
小甲鱼Python第三讲(小插曲之变量和字符串)
查看>>
小甲鱼Python第十一讲(一个打了激素的数组2)
查看>>
小甲鱼Python第十三讲(戴上了枷锁的列表)
查看>>
小甲鱼Python第十四讲(各种奇葩的内置方法)
查看>>
小甲鱼Python第十五讲(格式化)
查看>>
小甲鱼Python第十七讲(Python的乐高积木)
查看>>
小甲鱼Python第十八讲(函数:灵活即强大)
查看>>
小甲鱼Python第十九讲(函数,我的地盘听我的)
查看>>
小甲鱼python第二十讲(内嵌函数和闭包)
查看>>
小甲鱼Python第二十一讲(lambda表达式)
查看>>
小甲鱼Python第二十二讲(递归)
查看>>
小甲鱼Python第二十三讲、第二十四讲(递归-这帮小兔崽子、汉诺塔)
查看>>
小甲鱼Python第二十五讲、第二十六讲(字典)
查看>>