您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān).NET如何生成數(shù)據(jù)庫(kù)的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
本文主要是回顧下從項(xiàng)目創(chuàng)建到生成數(shù)據(jù)到數(shù)據(jù)庫(kù)(代碼優(yōu)先)的全部過(guò)程。采用EFCore作為ORM框架。
本次示例環(huán)境:vs2019、net5、mysql
本次事例代碼是用過(guò)vs2019創(chuàng)建的ASP.NET Core Web API項(xiàng)目
可以通過(guò)可視化界面創(chuàng)建或者通過(guò)命令行創(chuàng)建
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" />
增加實(shí)體類(lèi)
[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("帳號(hào)")] [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("創(chuàng)建人")] [StringLength(20)] [Required] public string Creater { get; private set; } [Comment("創(chuàng)建時(shí)間")] [Required] public DateTime CreateTime { get; private set; } [Comment("修改人")] [StringLength(20)] [Required] public string Modifyer { get; private set; } [Comment("修改時(shí)間")] [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; } }
這種只是增加實(shí)體類(lèi)類(lèi)型的一種方式,可能這種看著比較亂,還可以通過(guò)OnModelCreating實(shí)現(xiàn),詳情看參考文檔
增加數(shù)據(jù)庫(kù)上下文OpenDbContext
public class OpenDbContext : DbContext { public OpenDbContext(DbContextOptions<OpenDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } }
Startup注入連接數(shù)據(jù)庫(kù)操作
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
結(jié)果
要看下生成的遷移文件是否是自己預(yù)期的那樣子,也可以在這一步就生成數(shù)據(jù)庫(kù),命令:Update-Database
增加OpenDbSend類(lèi),添加數(shù)據(jù)種子
public class OpenDbSend { /// <summary> /// 生成數(shù)據(jù)庫(kù)以及數(shù)據(jù)種子 /// </summary> /// <param name="dbContext">數(shù)據(jù)庫(kù)上下文</param> /// <param name="loggerFactory">日志</param> /// <param name="retry">重試次數(shù)</param> /// <returns></returns> public static async Task SeedAsync(OpenDbContext dbContext, ILoggerFactory loggerFactory, int? retry = 0) { int retryForAvailability = retry.Value; try { dbContext.Database.Migrate();//如果當(dāng)前數(shù)據(jù)庫(kù)不存在按照當(dāng)前 model 創(chuàng)建,如果存在則將數(shù)據(jù)庫(kù)調(diào)整到和當(dāng)前 model 匹配 await InitializeAsync(dbContext).ConfigureAwait(false); //if (dbContext.Database.EnsureCreated())//如果當(dāng)前數(shù)據(jù)庫(kù)不存在按照當(dāng)前 model創(chuàng)建,如果存在則不管了。 // 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> /// 初始化數(shù)據(jù) /// </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); } }
設(shè)置項(xiàng)目啟動(dòng)時(shí)候調(diào)用
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, $"項(xiàng)目啟動(dòng)出錯(cuò) {ex.Message}"); } } await host.RunAsync().ConfigureAwait(false); }
啟動(dòng)項(xiàng)目,自動(dòng)生成數(shù)據(jù)庫(kù)
表結(jié)構(gòu)如下
如果后期數(shù)據(jù)庫(kù)字段或者結(jié)構(gòu)有變動(dòng),可以再次生成遷移文件然后生成數(shù)據(jù)庫(kù)
/// <summary> /// 用戶(hù)接口 /// </summary> public interface IUserService { string GetName(); /// <summary> /// 查詢(xún)用戶(hù)信息 /// </summary> /// <param name="account"></param> /// <returns></returns> Task<User> GetDetailsAsync(string account); } /// <summary> /// 用戶(hù)實(shí)現(xiàn) /// </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類(lèi),然后只查詢(xún)需要的內(nèi)容,不直接返回實(shí)體類(lèi)
控制器方法
/// <summary> /// 查詢(xún)用戶(hù)詳情 /// </summary> /// <param name="account"></param> /// <returns></returns> [HttpGet] public async Task<ActionResult<User>> GetDetailsAsync(string account) { return await _userService.GetDetailsAsync(account).ConfigureAwait(false); }
查詢(xún)結(jié)果
{ "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" }
感謝各位的閱讀!關(guān)于“.NET如何生成數(shù)據(jù)庫(kù)”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。