Asp.Net Core 項目實戰之許可權管理系統(3) 通過EntityFramework Core使用PostgreSQL

来源:http://www.cnblogs.com/fonour/archive/2016/09/19/5886292.html
-Advertisement-
Play Games

0 Asp.Net Core 項目實戰之許可權管理系統(0) 無中生有 1 Asp.Net Core 項目實戰之許可權管理系統(1) 使用AdminLTE搭建前端 2 Asp.Net Core 項目實戰之許可權管理系統(2) 功能及實體設計 3 Asp.Net Core 項目實戰之許可權管理系統(3) 通過 ...


0 Asp.Net Core 項目實戰之許可權管理系統(0) 無中生有

1 Asp.Net Core 項目實戰之許可權管理系統(1) 使用AdminLTE搭建前端

2 Asp.Net Core 項目實戰之許可權管理系統(2) 功能及實體設計

3 Asp.Net Core 項目實戰之許可權管理系統(3) 通過EntityFramework Core使用PostgreSQL

4 Asp.Net Core 項目實戰之許可權管理系統(4) 用戶登錄

github源碼地址

0 PostgreSQL安裝及配置

0.0 PostgreSQL簡介

既然Asp.Net Core最大的特性就是跨平臺,就搭配使用一個可以跨平臺的資料庫。PostgreSQL是一個功能強大的開源資料庫系統。經過長達15年以上的積極開發和不斷改進,PostgreSQL已在可靠性、穩定性、數據一致性等獲得了業內極高的聲譽。目前PostgreSQL可以運行在所有主流操作系統上,包括Linux、Unix(AIX、BSD、HP-UX、SGI IRIX、Mac OS X、Solaris和Tru64)和Windows。PostgreSQL是完全的事務安全性資料庫,完整地支持外鍵、聯合、視圖、觸發器和存儲過程(並支持多種語言開發存儲過程)。它支持了大多數的SQL:2008標準的數據類型,包括整型、數值值、布爾型、位元組型、字元型、日期型、時間間隔型和時間型,它也支持存儲二進位的大對像,包括圖片、聲音和視頻。PostgreSQL對很多高級開發語言有原生的編程介面,如C/C++、Java、.Net、Perl、Python、Ruby、Tcl 和ODBC以及其他語言等,也包含各種文檔。

0.1 PostgreSQL安裝及配置

自行去PostgreSQL官網下載符合你自己系統的版本,開始安裝,從我自己的安裝體驗來看,沒什麼需要特別註意的地方,只需要按照提示一步步安裝即可,在最後的時候根據需要選擇以下語言,設置超級用戶角色postgres的登錄密碼即可。

創建一個系統使用的角色

打開安裝好的PostgreSQL資料庫,輸入密碼進入管理界面。右鍵“登錄角色”,創建一個名稱為“fonour”的角色,在“角色許可權”頁簽中把所有能能勾選的功能都勾選上。

1

右鍵PostgreSQL伺服器,選擇斷開伺服器。接著右鍵,單擊“屬性”菜單,在彈出視窗的用戶名出輸入剛纔新建的“fonour”角色,輸入密碼並勾選記住密碼。確定,連接即可。

1 使用EntityFrameworkCore的CodeFirst方式創建資料庫

1.0 在Fonour.EntityFrameworkCore項目中創建DbContext

由於EF Core跟PostgreSQL都需要現學現用,EF Core的使用跟EF6.0還是有很多不同的,在使用的過程中遇到了不少的問題,尤其是針對PostgreSQL使用Guid類型的主鍵,後面會把這些坑做一個簡單的記錄。

0 添加相關依賴項

需要添加的相關依賴及說明如下:

  • Npgsql.EntityFrameworkCore.PostgreSQL

      PostgreSQL數據提供的支持EF Core的基礎類庫,是通過EF Core使用PostgreSQL資料庫的根本。

  • Npgsql.EntityFrameworkCore.PostgreSQL.Design

      使用Guid(對應Postgre數據的類型為uuid)類型的主鍵必須,int/long類型的主鍵不添加也沒問題。

  • Microsoft.EntityFrameworkCore.Tools

      EF Core工具,CodeFirst資料庫遷移相關操作必須。

  • Fonour.Domain

      我們自己創建的一個類庫項目,其中包含了組織機構、功能、角色、用戶等實體的定義。

添加相關引用依賴的方式有多種,可以通過NuGet程式包管理器控制台的Install-Packege命令

PM> Install-Package Npgsql.EntityFrameworkCore.PostgreSQL
PM> Install-Package Npgsql.EntityFrameworkCore.PostgreSQL.Design
PM> Install-Package Microsoft.EntityFrameworkCore.Tools

或者直接在NuGet程式包管理器中搜索相關類庫,進行安裝

1

最直接的方法是直接修改project.json配置文件,project.json配置文件最終修改後內容如下。

{
  "version": "1.0.0-*",

  "dependencies": {
    "Fonour.Domain": "1.0.0-0",
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
    "NETStandard.Library": "1.6.0",
    "Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.1",
    "Npgsql.EntityFrameworkCore.PostgreSQL.Design": "1.0.1"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "tools": {
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview2-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    }
  }
}

註意,frameworks部分,如果預設是netstandard1.6框架,必須進行修改,否則會提示不支持相關依賴項。

1 創建DbContext

根據EF Core對多對多關聯關係的要求,增加了UserRole、RoleMenu兩個關聯關係實體,同時對原有實體進行了調整。

public class UserRole
{
    public Guid UserId { get; set; }
    public User User { get; set; }

    public Guid RoleId { get; set; }
    public Role Role { get; set; }

}
public class RoleMenu
{
    public Guid RoleId { get; set; }
    public Role Role { get; set; }

    public Guid MenuId { get; set; }
    public Menu Menu { get; set; }
}

在Fonour.EntityFrameworkCore項目下新建一個數據上下文操作類,命名為“FonourDBContext”,其中增加許可權管理系統相關實體的DbSet的定義。最終代碼如下:

public class FonourDbContext : DbContext
{
    public FonourDbContext(DbContextOptions<FonourDbContext> options) : base(options)
    {

    }
    public DbSet<Department> Departments { get; set; }
    public DbSet<Menu> Menus { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<UserRole> UserRoles { get; set; }
    public DbSet<RoleMenu> RoleMenus { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        //UserRole關聯配置
        builder.Entity<UserRole>()
          .HasKey(ur => new { ur.UserId, ur.RoleId });

        //RoleMenu關聯配置
        builder.Entity<RoleMenu>()
          .HasKey(rm => new { rm.RoleId, rm.MenuId });
        builder.Entity<RoleMenu>()
          .HasOne(rm => rm.Role)
          .WithMany(r => r.RoleMenus)
          .HasForeignKey(rm => rm.RoleId).HasForeignKey(rm => rm.MenuId);

        //啟用Guid主鍵類型擴展
        builder.HasPostgresExtension("uuid-ossp");

        base.OnModelCreating(builder);
    }
}

1.1 在Fonour.MVC項目中進行資料庫連接相關配置

0 添加相關依賴項

在Asp.Net Core中,使用json格式的配置文件進行系統相關參數的配置,將相關配置文件通過ConfigurationBuilder進行統一管理,得到IConfigurationRoot的配置實例,獲取相關配置文件配置節點的信息。想要使用配置文件相關服務,需要添加一下依賴。

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.FileExtensions
  • Microsoft.Extensions.Configuration.Json

還需要添加對Fonour.EntityFrameworkCore項目的引用。

最終Fonour.MVC項目的project.json文件配置如下:

{
  "dependencies": {
    "Microsoft.NETCore.App": "1.0.1",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.AspNetCore.Mvc": "1.0.1",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
    "Microsoft.Extensions.Configuration": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Fonour.EntityFrameworkCore": "1.0.0-*"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  },
  "runtimes": {
    "win10-x64": {}
  }
}

1 增加appsettings.json配置文件

右鍵Fonour.MVC項目,新增一個Asp.Net配置文件類型,名稱為appsettings.json的配置文件。

1

appsettings.json文件目前主要內容為定義資料庫連接字元串,內容如下:

{
  "ConnectionStrings": {
    "Default": "User ID=fonour;Password=123456;Host=localhost;Port=5432;Database=Fonour;Pooling=true;"
  }
}

2 啟用資料庫連接

首先在Startup.cs中定義一個IConfigurationRoot的屬性,然後在系統啟動類Startup.cs的構造函數中,對配置文件進行管理。

public IConfigurationRoot Configuration { get; }
public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

在ConfigureServices方法中獲取資料庫連接字元串,並添加資料庫連接服務。

public void ConfigureServices(IServiceCollection services)
{
    //獲取資料庫連接字元串
    var sqlConnectionString = Configuration.GetConnectionString("Default");

    //添加數據上下文
    services.AddDbContext<FonourDbContext>(options =>
        options.UseNpgsql(sqlConnectionString)
    );

    services.AddMvc();
}

1.2 使用CodeFirst資料庫遷移命令創建資料庫

在EntityFrameworkCore中資料庫遷移有兩種方式。

0 使用命令行工具

在應用程式根目錄按住shift鍵同時單擊滑鼠右鍵,選擇“在此處打開命令視窗”,輸入資料庫遷移的命令

dotnet ef migrations add Init

dotnet ef database update

1 使用程式包管理器控制台

在程式包管理器控制臺中預設項目選擇Fonour.EntityFrameworkCore,輸入以下命令,自動創建資料庫遷移文件。

Add-Migration Init

註意,一定要將Fonour.MVC設置為啟動項目。

執行完成後,項目中增加了資料庫遷移文件。

1

輸入以下命令,進行資料庫更新操作。

Update-Database

提示更新完成後,查看我們的資料庫,會發現資料庫及資料庫表已經創建完成。

1

2 數據初始化

為保證系統正常運行,我們需要對系統進行數據初始化,要初始化的數據包括一下內容:

  • 用戶表插入一條用戶名為admin的超級管理員用戶信息
  • 功能菜單表增加組織機構管理、角色管理、用戶管理、功能管理四條基本數據。
  • 組織機構表插入一條組織機構信息(主要是因為用戶表存在一個DepartmentId的外鍵)

在Fonour.EntityFrameworkCore項目中增加一個新的數據初始化類,命名為SeedData.cs,修改內容如下:

public static class SeedData
{
    public static void Initialize(IServicePr
    {
        using (var context = new FonourDbCon
        {
            if (context.Users.Any())
            {
                return;   // 已經初始化過數據
              }
            Guid departmentId = Guid.NewGuid
            //增加一個部門
              context.Departments.Add(
               new Department
               {
                   Id = departmentId,
                   Name = "Fonour集團總部",
                   ParentId = Guid.Empty
               }
            );
            //增加一個超級管理員用戶
              context.Users.Add(
                 new User
                 {
                     UserName = "admin",
                     Password = "123456", //
                     Name = "超級管理員",
                     DepartmentId = departme
                 }
            );
            //增加四個基本功能菜單
              context.Menus.AddRange(
               new Menu
               {
                   Name = "組織機構管理",
                   Code = "Department",
                   SerialNumber = 0,
                   ParentId = Guid.Empty,
                   Icon = "fa fa-link"
               },
               new Menu
               {
                   Name = "角色管理",
                   Code = "Role",
                   SerialNumber = 1,
                   ParentId = Guid.Empty,
                   Icon = "fa fa-link"
               },
               new Menu
               {
                   Name = "用戶管理",
                   Code = "User",
                   SerialNumber = 2,
                   ParentId = Guid.Empty,
                   Icon = "fa fa-link"
               },
               new Menu
               {
                   Name = "功能管理",
                   Code = "Department",
                   SerialNumber = 3,
                   ParentId = Guid.Empty,
                   Icon = "fa fa-link"
               }
            );
            context.SaveChanges();
        }
    }
}

在Fonour.MVC項目的Startup.cs中Configure方法最後增加數據初始化的操作。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole();

    if (env.IsDevelopment())
    {
        //開發環境異常處理
        app.UseDeveloperExceptionPage();
    }
    else
    {
        //生產環境異常處理
        app.UseExceptionHandler("/Shared/Error");
    }
    //使用靜態文件
    app.UseStaticFiles();
    //使用Mvc,設置預設路由為系統登錄
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Login}/{action=Index}/{id?}");
    });

    SeedData.Initialize(app.ApplicationServices); //初始化數據
}

運行程式。查看資料庫,發現初始化數據已經生成成功。

1

2

3

3 踩過的一些坑

  • 使用Guid類型的主鍵一定要添加"Npgsql.EntityFrameworkCore.PostgreSQL.Design": "1.0.1"的引用,註意1.0.0版本是不支持的。
  • 要想使用Guid類型的主鍵一定要在DbContext的 OnModelCreating 重寫方法中啟用uuid的擴展 builder.HasPostgresExtension("uuid-ossp");
  • 關於多對關係的實體設計

      在以前的EntityFramework中,多對多關係的實體,只需要創建兩個實體,兩個實體分別包含一個對方集合的導航屬性即可,是不需要創建關聯實體類的。如,User實體中包含一個ICollection<Role> Roles的導航屬性,同時Role實體中包含一個ICollection<User> Users的導航屬性,EF會根據實體間的關係自動創建一個User_Role中間表,若想修改中間表名,進行相關配置即可。

      EF Core中必須創建關聯關係的實體才行。

  • EF Core暫不支持LayzingLoad

4 總結

本節主要是研究怎樣通過EntityFramework Core使用PostgreSQL,通過CodeFirst資料庫遷移的方式根據設計好的實體進行資料庫的創建,最後我們根據系統需要,進行了一些相關數據的初始化。

接下來要實現用戶登錄功能。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 我們知道,在 MVC 應用程式中,有一部分約定的內容。其中關於 Controller 的約定是這樣的。 每個 Controller 類的名字以 Controller 結尾,並且放置在 Controllers 目錄中。 Controller 使用的視圖是在 Views 主目錄的一個子目錄中,這個 ...
  • 接著上期的文章繼續說非同步與並行 並行來自於線程的方法實現,非同步不一定。這句話,暈倒一大片程式員。 首先,多線程式是實現非同步一種方法,兩者的共同目的:使主線程保持對用戶操作的實時響應,如點擊、拖拽、輸入字元等。使主程式看起來實時都保持著等待用戶響應的狀態,而後臺卻有若幹件事情在自己乾。按消耗資源所在地 ...
  • 一、B/S和C/S 1、C/S C/S 架構是一種典型的兩層架構,其全程是Client/Server,即客戶端伺服器端架構,其客戶端包含一個或多個在用戶的電腦上運行的程式,而伺服器端有兩種,一種是資料庫伺服器端,客戶端通過資料庫連接訪問伺服器端的數據;另一種是Socket伺服器端,伺服器端的程式通過 ...
  • using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Syste ...
  • 想法:將屏幕截圖作為程式背景圖,在之上彈出提示視窗,選擇確定後進行定時圖片隨機位置顯示。(支持ESC鍵退出) 需要添加的控制項:Timer 需要修改的Form1屬性為下圖紅色區域: 資源文件的添加:添加->新建項->資源文件 ESC鍵退出程式: 在Form1.Designer.cs中增加 this.K ...
  • 相同點: 1、都可以被繼承 2、都不能被實例化 3、都可以包含方法聲明 4、派生類必須實現未實現的方法 區別: 1、抽象基類可以定義欄位、屬性、方法實現。介面只能定義屬性、索引器、事件、和方法聲明,不能包含欄位。 2、抽象類是一個不完整的類,需要進一步細化,而介面是一個行為規範。微軟的自定義介面總是 ...
  • 1.出現invalid signature 如果是微信web開發著工具出現的話,那麼可以用手機試試看,是不是有問題。 2.出現支付一閃而過 一般是授權問題,需要在微信支付-開發配置-測試授權目錄裡面添加授權目錄(註意是區分大小寫的,精確到Controller就行了,也就是二級目錄) 2.Redire ...
  • 使用jQuery調用WebApi有時會遇到跨域的問題,今天介紹一種可以簡單解決跨域問題的方法。 當我們跨域請求WebAPI的時候會提示以下信息: XMLHttpRequest cannot load http://localhost:9641/api/news/GetData. No 'Access ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...