国产化之路-统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作
引言
經過前期的準備工作,.net core 3.1的運行環境和WEB服務器已經搭建完畢,這里需要注意一下,達夢DM8數據庫對于Entity Framework Core 3.1 的驅動在NuGet官方源上并沒有正式發布,需要從Win64安裝版本中的drivers/dotNet提取,這里需要事先準備。
創建項目
出于開發的習慣和便利性,項目的開發和調試都還是在windows的環境下面進行,打開Visual Studio 2019,創建新項目,使用ASP.NET Core web應用程序模板,項目名稱自己取一下,我這里取名DmExample,版本選擇ASP.NET Core 3.1 ,為HTTPS 配置勾選去掉,暫時不需要HTTPS
點擊”創建“按鈕后,稍微等待一會兒,默認的MVC項目搭建完成。在Controllers目錄下只有一個HomeController.cs文件,點擊運行看一下:
已經可以正常跑起來,接下來我們要在這個基礎下開始添加模型、連接達夢數據庫、創建數據庫、添加簡單的增刪改查的操作。
添加驅動
在添加應用之前,為了能夠連接數據庫和創建表,我們首先要使用NuGet包管理工具,安裝如下支持包:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design
安裝完以上包后,我們需要安裝EF Core的達夢數據庫驅動,前面提到過在官方的NuGet源中并沒有達夢的EF Core驅動,但在達夢的安裝盤上有提供,所以需要對NuGet包管理器的程序包源進行添加設置,將達夢數據庫安裝源中的EFCore.Dm3.1,DmProvider作為包源引入,然后再安裝。
在NuGet包管理器中,點擊右上角(紅框框起來的齒輪圖標),彈出選項窗口:
點擊窗口右上角的加號圖標,然后名稱輸入EFCore.Dm3.1,源路徑選擇你光盤鏡像下面的source\drivers\dotNet\EFCore.Dm3.1。以同樣的方式將DmProvider包源引入,源路徑:source\drivers\dotNet\DmProvider,包源設置完成后就可以安裝。
如上圖所示,選擇程序包源EFCore.Dm3.1后,在瀏覽面板中會列出達夢的EntityFramework Core的驅動包,選擇它然后點擊”安裝“。
同樣,選擇程序包源DmProvider后,在瀏覽面板中會列出達夢的DmProvider的驅動包,選擇它然后點擊”安裝“。這里有個地方需要注意,在NuGet包源上可以搜索到DmProvider 2.0版本的包,雖然版本高于我們當前的本地版本,但這個是.NetFramework版本的,于2017年9月7日發布,不適用于Core版本的,請不要安裝或更新。
添加模型
驅動安裝完成后,我們要添加一個數據模型,在Models目錄下添加一個User.cs用戶模型,具體代碼如下:
using System; using System.ComponentModel.DataAnnotations;namespace DmExample.Models {/// <summary>/// 用戶模型/// </summary>public class User{public User(){Id = Guid.NewGuid().ToString("N");CreateTime = DateTime.Now;}[Key]public string Id { get; set; }/// <summary>/// 姓名/// </summary>public string Name { get; set; }/// <summary>/// 年齡/// </summary>public int? Age { get; set; }/// <summary>/// 性別/// </summary>public bool? Gender { get; set; }/// <summary>/// 創建日期/// </summary>public DateTime? CreateTime { get; set; }} }屬性不多,就ID、姓名、年齡、性別、創建日期,分別使用了字符串、整型、布爾型和日期類型,對一些常規性的屬性做一下數據表屬性對應測試。
創建數據庫
添加數據庫上下文
在項目中添加DbContext目錄,在目錄中添加一個名為DmContext.cs的類作為達夢數據庫上下文,具體代碼如下:
using DmExample.Models; using Microsoft.EntityFrameworkCore;namespace DmExample.DbContext {/// <summary>/// 達夢數據庫上下文/// </summary>public class DmContext : Microsoft.EntityFrameworkCore.DbContext{/// <summary>/// 用戶/// </summary>public DbSet<User> Users { get; set; }public DmContext(DbContextOptions<DmContext> options) : base(options){}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.Entity<User>().ToTable("sys_user");}} }如上代碼所示,DmContext繼承自Microsoft.EntityFrameworkCore.DbContext,添加了用戶User的DbSet,重載OnModelCreating方法,將User模型與數據庫的sys_user表建立映射關系,當然也可以不指定映射關系,在不指定的情況下,默認映射成Users數據表。目前我們還沒創建數據庫,數據庫里也還沒有這個數據表,接下來需要配置數據庫連接。
配置數據庫連接
(1)添加數據庫連接字符串
打開項目中的appsettings.json配置文件,添加數據庫連接字符串,如下所示:
{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"AllowedHosts": "*","ConnectionStrings": {"DmExample": "Server=localhost;Database=DmExampleDB;User=SYSDBA;Password=111111;"} }我們在appsettings.json配置文件中添加了一個ConnectionStrings的配置項,用來設置數據庫連接字符串,連接字符串命名為DmExample,字符串的格式同我們連接SqlServer類似,Server為數據庫地址、Database為數據庫名稱、User和Password分別為連接數據庫賬號和密碼,需要注意的一點是設置數據庫地址的時候如果是本地地址,咱們往往習慣性地用Server=.來表示,但是達夢數據庫不認識這種表示,會無法連接數據庫,需要把點替換成localhost或127.0.0.1才行,這個注意一下。
(2)注冊數據庫上下文
完成數據庫連接字符串的添加后,我們需要在Starup.cs類中對當前的數據庫上下文進行注冊,微軟已經為我們提供上下文注冊的中間件,只要調用它就可以了,具體代碼如下:
public void ConfigureServices(IServiceCollection services) {services.AddControllersWithViews();// 注冊DbContextservices.AddDbContext<DmContext>(options =>options.UseDm(Configuration.GetConnectionString("DmExample"))); }如上代碼所示,DmContext是咱們創建的達夢數據庫上下文,DmExample是我們在appsettings.json配置文件中添加的數據庫連接字符串,通過Configuration.GetConnectionString方法獲取該數據庫連接字符串。這里注意這個代碼:options.UseDm,我們連接SqlServer數據庫的時候是使用options.UseSqlServer,如果我們以后連接MySql數據庫時是使用options.UseMySQL,使用不同的數據庫需要對應的數據庫驅動,UseDm就是由達夢數據庫驅動提供的方法,至此數據庫的連接我們已配置完成,接下來我們要創建數據庫。
創建數據庫
數據庫連接配置完成后,我們直接使用Visual Studio 2019的程序包管理器控制臺,通過命令方式來創建數據庫,首先輸入如下命令(initDB是我們取的名字,沒有強制規定):
add-migration 'initDB'The add-migration command is one of the key commands in code first migrations. When you make changes to your domain model and need them dded into your database you create a new migration. This is done with the Add-Migration command. In it’s simplest form you need only toprovide a migration name.
add-migration命令是code first migration中的關鍵命令之一。當您對領域域模型進行更改并需要將它們時添加到數據庫中,您將創建一個新的遷移。這是通過Add-Migration命令完成的。用最簡單的形式,你只需要提供遷移名稱。
命令執行成功后會在當前的項目中創建Migrations目錄, 在這個目錄中我們發現有兩個文件,其中一個文件由當前創建日期加上我們之前add 后面創建名字的一個記錄20201002080053_initDB記錄了此次更新的部分,由于我們是第一次初始化,所以里面記錄了全部表結構內容,下次我們再次使用該命令做更新時,會再次添加新的記錄文件,只記錄更新部分;另一個名為 DmContextModelSnapshot的文件是 Migrations生成的IModel狀態的快照的基類,里面記錄了要生成db的內容。
接下來執行更新數據庫命令:
update-database出現如上圖所示表示執行成功,為驗證是否創建數據表,我們打開達夢的數據庫管理工具,查看數據庫是否已存在:
我們在模式->SYSDBA->表下面發現了sys_user這張表,在表空間->MAIN->表也能夠看到這張表。數據表應該是創建成功了,但是就是沒有發現我們在數據庫連接字符串中指定的數據庫名DmExampleDB,估計是達夢的數據庫結構和SqlServer有所區別,這個放在后面系統性地再去學習了,至此我們數據庫創建完畢,接下來開始添加針對用戶的CURD操作了。
添加增刪改查操作
我們選中項目中的Controllers目錄,點擊右鍵彈出下拉菜單依次點擊添加->控制器,彈出添加已搭建基架的新項窗口,選擇”視圖使用Entity Framework的MVC控制器“,然后點擊”確定“按鈕,如下圖所示:
點擊”確定“按鈕后彈出添加視圖的配置窗口,模型類選擇User,數據上下文類選擇DmContext,控制器名稱默認UsersController,然后點擊"添加"按鈕。
稍微等待片刻后,我們看到在Controllers目錄中已經生成了UsersController類,打開這個類文件,增刪改查的代碼都已經生成;點開Views視圖目錄,下面新增了Users目錄,在該目錄里邊增刪改查的視圖也已全部生成。
用戶操作的功能基本都有了,我們稍作改造就可以使用了。首先,我們要在首頁上添加用戶的User的入口菜單,以便對用戶進行操作,打開Views/Shared/_Layout.cshtml,添加如下圖代碼:
另外,我們在User模型類中添加了構造函數,對新建的User對象的Id和CreateTime,設置了默認值,所以我們在創建的時候就不必要再輸這兩個值了,編輯Views/Users/Create.cshtml,去掉這兩個屬性的代碼:
編輯Views/Users/Edit.cshtml,將編輯CreateTime的輸入框修改為隱藏類型,編輯的時候不需要輸入了:
最后,我們再修改一下Views/Users/Index.cshtml,在列表頁里添加ID列,把它顯示出來:
至此我們代碼修改完畢。
測試運行
完成以上的創建和修改,我們直接在本機上先測試運行一下,頁面效果如下:
首頁上多了一個User菜單,我們點擊這個菜單項后,顯示如下頁面:
這個是用戶列表頁面,因為我們還未添加任何用戶,所以當前列表是空的。我們點擊"Create New"鏈接,跳轉至添加用戶的頁面,來添加一個新用戶試試:
注意:性別是布爾類型的,我們輸入true或false來表示,點擊Create按鈕添加用戶,成功后自動跳轉到用戶列表頁面,如下圖所示:
添加完成后,列表頁面上顯示出了一條記錄,為了印證記錄已經插入到sys_user表里,我們打開達夢的數據庫管理工具進行查看:
接下來,我們再測試一下編輯、詳細、刪除操作,也都沒有問題,這里不再貼圖,到此我們完成了簡單的測試,下一步將項目先發布到本地,然后部署到Web服務器上。
注意,我們發布的時候需要修改一下數據庫的連接字符串,連接地址要修改為服務器上的數據庫,然后在程序包管理器控制臺上再次運行update-database命令,主要目的是在服務器上創建數據庫,當然如果已經創建了就不用去執行這個命令了。然后,依次點擊生成->發布DmExample,彈出發布配置窗口,發布目標選擇”文件夾“:
文件夾位置默認即可,然后點擊”完成“按鈕
摘要處默認即可,點擊"發布"按鈕,完成發布操作,系統會將編譯的發布版本復制到指定的目標位置。
項目部署
項目的部署請參考《國產化之路-安裝WEB服務器》章節中的”發布站點“,這里不再詳細介紹,這里補充一項,在發布站點的時候我們需要配置反向代理,ASP.NET Core默認發布的端口號是5000,所以在配置節中我們設置的端口號對應的也是5000,但當我們的Web服務器發布多個站點時,不能使用同一個端口,那么我們如何去修改ASP.NET Core默認發布的端口號呢?經查閱資料,我們只需要在appsettings.json的配置文件里添加urls配置屬性即可,具體如下:
{"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"AllowedHosts": "*","ConnectionStrings": {"DmExample": "Server=localhost;Database=DmExampleDB;User=SYSDBA;Password=dx2263111;"},"urls": "http://localhost:5005" }我們這里設定的默認端口為5005,然后在Web服務器里對該站點的反向代理中的端口號做相應的調整:
# DmExample location / {proxy_pass http://localhost:5005;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection keep-alive;proxy_set_header Host $host;proxy_cache_bypass $http_upgrade;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme; }一切準備就緒,在Web服務器上發布完成后,打開站點顯示正常,但是當我們插入一條用戶數據后報錯了。
糾錯
同一個站點,在我們的開發機上測試都沒有問題,然后發布到統信的操作系統下就出問題,接著又試了一下將數據庫連到Web服務器,運行環境還是在開發機上試了一下也沒有問題,應該來講大概率就是環境問題了,那環境問題導致哪里出問題了呢?上面的錯誤信息,并沒有告訴我們問題出在哪里,大概意思是講讓我們切換成開發模式可以查看到更詳細的錯誤信息,那么我們切換成開發模式看看,暫停這個站點的守護進程,使用終端進入站點目錄執行下面命令:
# 切換成"Development"模式 export ASPNETCORE_ENVIRONMENT=development # 運行站點 dotnet DmExample.dll然后使用瀏覽器打開該站點,執行用戶插入操作,頁面顯示信息變成如下顯示:
反饋的應該是插入的某個字段數據類型不對,原本輸入的是數字的位置輸入了非數字的字符,導致無法插入造成的,但未給出具體是哪個字段,分析我們當前的用戶數據類型也就只有年齡是數字類型的,但這個有點不太可能,我們輸入的確實是數字,其它和數字搭邊的就是日期類型了。我們對這兩個字段做了排查,結果發現是日期類型DateTime的原因,那為什么會這樣呢?我們做一個簡單的日期類型輸出然后分別在開發機上和Web服務器上去運行試試看,結果如下:
上圖第一張是在windows開發機上輸出,第二張是在統信UOS上輸出。第一個時間是DateTime.Now輸出,第二個時間是特定時間輸出,主要目的是為區分上下午。很明顯看到,在開發機上是24小時格式的,但統信UOS是12小時格式的,并用中文標識出了上午、下午,在插入的時候就現了問題,但看了統信UOS時間設置也是24小時制的,網上找了一下,這個問題并不是只是統信UOS獨有的,在Linux上都有這個問題,找了一下解決辦法,需要在程序開始時設置CultureInfo.DefaultThreadCurrentCulture,我們可以把它加在Program的Main入口上,代碼如下:
public static void Main(string[] args) {// 跨平臺 DateTime 中文 上午 下午 解決方案CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("zh-CN", true){DateTimeFormat = { ShortDatePattern = "yyyy-MM-dd", FullDateTimePattern = "yyyy-MM-dd HH:mm:ss", LongTimePattern = "HH:mm:ss" }};CreateHostBuilder(args).Build().Run(); }CultureInfo.DefaultThreadCurrentCulture屬性用來 獲取或設置當前應用程序域中線程的默認區域性,從上面的代碼理解是,將其設置中文區域,然后指定了短日期、完整時間以及長時間的格式,這里注意HH和hh的區別,HH是24小時制的,而hh是12小時制的。我們在日期輸出小例子里加上這一段代碼然后再看看其在來個系統統上的輸出是怎么樣的:
上圖第一張是windows開發機,第二張是統信UOS,我們發現時間格式已經和開發機上格式一致了,然后我們再次發布站點,進行測試,問題解決。
小結
通過以上的簡單案例,我們實現了在統信UOS操作系統,基于達夢D8數據庫,使用.net core 3.1和EntityFramework core的簡單增、刪、改、查的操作,在這個過程中我們發現windows和Linux類操作系統日期顯示格式的不同對我們所開發的應用造成的影響,這個問題應該并不是統信UOS獨有的問題。我們當前只是個開端,隨著業務的深入,所遇到的問題也將會越來越復雜,具體問題需要具體分析,不管是什么樣的問題我們相信都有解決辦法。
參考資料
DateTime中文上午下午解決方案:https://blog.csdn.net/i2blue/article/details/105798392
CultureInfo.DefaultThreadCurrentCulture屬性介紹:https://docs.microsoft.com/zh-cn/dotnet/api/system.globalization.cultureinfo.defaultthreadcurrentculture?view=netcore-3.1
在 ASP.NET Core 中使用多個環境:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/environments?view=aspnetcore-3.1
EF Core連接達夢數據庫參考1:https://blog.csdn.net/lordwish/article/details/104501226
EF Core連接達夢數據庫參考2:https://blog.csdn.net/lordwish/article/details/108532022
總結
以上是生活随笔為你收集整理的国产化之路-统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在.NET中使用DiagnosticSo
- 下一篇: 网络知识 | 《图解TCP/IP》读书笔