1. 程式人生 > 其它 >ASP.NET Core通過EF Core連線資料庫

ASP.NET Core通過EF Core連線資料庫

使用EF Core的Code First模式,通過遷移來同步資料庫與模型.

環境: JetBrains Rider Window10 .NET5

一. 建立專案

  1. 使用JetBrains Rider建立一個web api專案

  2. 使用NuGet安裝依賴包

    • Microsoft.EntityFrameworkCore
    • Microsoft.EntityFrameworkCore.Tools
    • Microsoft.EntityFrameworkCore.SqlServer 此依賴包根據使用的資料庫安裝相應的包, 這裡使用的是SQL Server
  3. 建立資料庫上下文

    • 在專案中建立一個Data資料夾,建立一個類TestDBContext

      using Microsoft.EntityFrameworkCore;
      
      namespace Test.Data
      {
          public class TestDBContext : DbContext
          {
              public TestDBContext(DbContextOptions<TestDBContext> options) : base(options){}
          }
      }
      
  4. 建立資料模型

    • 在專案中建立一個Models資料夾,建立部門類Department, 員工類Personnel

      using System.Collections.Generic;
      using System.ComponentModel.DataAnnotations;
      using System.ComponentModel.DataAnnotations.Schema;
      
      namespace Test.Models
      {
          /// <summary>
          /// 部門類
          /// </summary>
          public class Department
          {
              [Key] // 主鍵
              [DatabaseGenerated(DatabaseGeneratedOption.Identity)]  //設定自增
              public int Id { get; set; }
              
              [Required]
              [MaxLength(50)]
              public string Name { get; set; }
      
              // Department 與 Personnel 一對多
              public ICollection<Personnel> Personnels { get; set; } = new List<Personnel>();
          }
      }
      
      using System.ComponentModel.DataAnnotations;
      using System.ComponentModel.DataAnnotations.Schema;
      
      namespace Test.Models
      {
          /// <summary>
          /// 員工類
          /// </summary>
          public class Personnel
          {
              [Key]
              [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
              public int Id { get; set; }
              
              [Required]
              [MaxLength(50)]
              public string Name { get; set; }
              
              public int Age { get; set; }
              
              [ForeignKey("Department")] // 外來鍵
              public int DepartmentId { get; set; }
          }
      }
      
  5. 在之前建立的資料庫上下文TestDBContext中註冊資料模型

    using Microsoft.EntityFrameworkCore;
    using Test.Models;
    
    namespace Test.Data
    {
        public class TestDBContext : DbContext
        {
            public TestDBContext(DbContextOptions<TestDBContext> options) : base(options){}
            
            // 註冊資料模型
            // 模型集的名稱與對應的表名相同
            public DbSet<Department> Departments { get; set; }
            public DbSet<Personnel> Personnels { get; set; }
        }
    }
    
  6. 在appsettings.json中新增資料庫連線字串

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "connectionStrings": {
        "SqlServerContext": "Data Source=伺服器名;Initial Catalog=資料庫名; User Id=使用者名稱;Password=密碼"
      }
    }
    
  7. 在Startup中註冊資料庫上下文TestDBContext

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.OpenApi.Models;
    using Test.Data;
    
    namespace Test
    {
        public class Startup
        {
            // 注入 IConfiguration:有關配置檔案最底層的一個介面型別
            public Startup(IConfiguration configuration)
            {
                _Configuration = configuration;
            }
    
            private IConfiguration _Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
                services.AddSwaggerGen(c => { c.SwaggerDoc("v1", 
                    new OpenApiInfo {Title = "Test", Version = "v1"}); });
                // 註冊資料庫上下文
                // _Configuration["connectionStrings:SqlServerContext"] 獲取資料庫連線字串
                services.AddDbContext<TestDBContext>(option
                    => option.UseSqlServer(_Configuration["connectionStrings:SqlServerContext"]));
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseSwagger();
                    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Test v1"));
                }
    
                app.UseHttpsRedirection();
    
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
            }
        }
    }
    
  8. 遷移

    • 開啟Terminal視窗或者cmd進入專案根目錄執行遷移命令: dotnet ef migrations add 本次遷移的名稱
    • 如果未安裝dotnet ef, 會無法執行
    • 安裝全域性dotnet ef
    • 再次執行遷移命令
    • 遷移成功後, 專案中有一個Migrations目錄, 儲存著每次遷移的記錄
  9. 更新資料庫

    • 執行dotnet ef database update
    • 資料庫更新成功, 資料庫就已經建立好了
    • 當資料模型發生改變時, 只用再次執行遷移/更新資料庫

二. 新增初始資料

  1. 在資料上下文TestDBContext中重寫OnModelCreating方法

    using System.Collections.Generic;
    using Microsoft.EntityFrameworkCore;
    using Test.Models;
    
    namespace Test.Data
    {
        public class TestDBContext : DbContext
        {
            public TestDBContext(DbContextOptions<TestDBContext> options) : base(options){}
            
            // 註冊資料模型
            // 模型集的名稱與對應的表名相同
            public DbSet<Department> Departments { get; set; }
            public DbSet<Personnel> Personnels { get; set; }
    
            // 控制資料庫和模型對映, 通過它可以自定義對映關係
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Department>()
                    .HasData(new List<Department>()
                    {
                        new Department() {Id = 1, Name = "人力資源部"},
                        new Department() {Id = 2, Name = "技術部"}
                    });
                modelBuilder.Entity<Personnel>()
                    .HasData(new List<Personnel>()
                    {
                        new Personnel() {Id = 1, Name = "張三", Age = 23, DepartmentId = 2},
                        new Personnel() {Id = 2, Name = "李四", Age = 20, DepartmentId = 1},
                        new Personnel() {Id = 3, Name = "王五", Age = 25, DepartmentId = 2}
                    });
                base.OnModelCreating(modelBuilder);
            }
        }
    }
    
  2. 遷移, 更新資料庫