博客
关于我
.NET之生成数据库全流程
阅读量:561 次
发布时间:2019-03-10

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

开篇语

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

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

创建项目

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

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

dotnet new webapi -o Net5ByDocker

创建实体类

安装组件

    
    

增加实体类

    [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://nlwvz.baihongyu.com/

你可能感兴趣的文章
第八届蓝桥杯——杨辉三角
查看>>
算法训练——字符串合并
查看>>
第七届蓝桥杯(国赛)——凑平方数
查看>>
信息学奥赛一本通【题目索引 + 解答】
查看>>
统计字符数
查看>>
MySQL事务
查看>>
什么时候需要重写HashCode()
查看>>
2021-04-23
查看>>
Linux编程基础之创建两个子进程而不创建孙子进程
查看>>
另一个树的子树
查看>>
hadoop 分布式文件系统的计算和高可用
查看>>
2021-05-08
查看>>
【Linux】VMware Workstation 不可恢复错误: (vcpu-0)
查看>>
VS中 fatal error LNK1123: 转换到 COFF 期间失败 的解决方法
查看>>
关于Img标签在固定宽高的容器内部以图片比例缩放存在
查看>>
python3---读写文件、POST表单请求、HTML处理、列表分割遍历,进行暴力破解用户名与密码
查看>>
Android Studio基础项目-布局XML设置的实战-全屏显示登录界面,去除按钮深颜色
查看>>
python --- 监控客户端是否存活
查看>>
pyhton---异常处理的终极语法、网页访问基本读取、网页访问异常处理
查看>>
Centos 7.3 计算本目录下的以特定名字文件夹个数
查看>>