1. 程式人生 > 程式設計 >.NET之生成資料庫全流程實現

.NET之生成資料庫全流程實現

開篇語

本文主要是回顧下從專案建立到生成資料到資料庫(程式碼優先)的全部過程。採用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.
js
on.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)]
        [Rewww.cppcns.com
quired] 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("修改人"DvQiE
)] [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

結果

.NET之生成資料庫全流程實現

要看下生成的遷移檔案是否是自己預期的那樣子,也可以在這一步就生成資料庫,命令: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("張三","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);
        }

生成資料庫

啟動專案,自動生成資料庫

.NET之生成資料庫全流程實現

表結構如下

.NET之生成資料庫全流程實現

如果後期資料庫欄位或者結構有變動,可以再次生成遷移檔案然後生成資料庫

查詢資料

    /// <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 awww.cppcns.comsync 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/www.cppcns.comentity-properties?tabs=data-annotations%2Cwithout-nrt

到此這篇關於.NET之生成資料庫全流程實現的文章就介紹到這了,更多相關.NET 生成資料庫內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!