Entity Framework Core使用控制臺(tái)程序生成數(shù)據(jù)庫(kù)表
一、引言
我們使用Code First的方式來(lái)生成數(shù)據(jù)庫(kù)表,我們先講解如何在控制臺(tái)項(xiàng)目中生成數(shù)據(jù)庫(kù)表。
在前面的文章中,我們是直接在控制臺(tái)項(xiàng)目中安裝的Mircosoft.EntityFrameworkCore,在真實(shí)的項(xiàng)目中,我們很少這樣使用,都是采用分層的結(jié)構(gòu),將EF Core有關(guān)的操作放在一個(gè)單獨(dú)的類庫(kù)項(xiàng)目里,下面的例子中我們就以這種分層的結(jié)構(gòu)來(lái)進(jìn)行講解。項(xiàng)目結(jié)構(gòu)如下圖所示:
項(xiàng)目結(jié)構(gòu):
- EFCoreTest.Con:控制臺(tái)項(xiàng)目,用來(lái)運(yùn)行程序,在項(xiàng)目中會(huì)引用EFCoreTest.Data。
- EFCoreTest.Data:類庫(kù)項(xiàng)目,基于.Net Standard。存放的是與EF Core相關(guān)的內(nèi)容。
- EFCoreTest.Model:類庫(kù)項(xiàng)目,基于.Net Standard。存放項(xiàng)目中使用到的實(shí)體類。
1、添加實(shí)體類
我們首先在EFCoreTest.Model類庫(kù)項(xiàng)目里添加Student實(shí)體:
namespace EFCoreTest.Model { public class Student { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public int Gender { get; set; } } }
2、添加Mircosoft.EntityFrameworkCore
我們?cè)贓FCoreTest.Data類庫(kù)里面添加Mircosoft.EntityFrameworkCore包:
我們使用SqlServer數(shù)據(jù)庫(kù),所以我們還要安裝Microsoft.EntityFrameworkCore.sqlServer包:
安裝完成以后我們添加EFCoreTest.Model的引用,然后添加數(shù)據(jù)上下文類,該類繼承自DbContext:
using EFCoreTest.Model; using Microsoft.EntityFrameworkCore; namespace EFCoreTest.Data { /// <summary> /// 數(shù)據(jù)上下文類,繼承自DbContext /// </summary> public class EFCoreDbContext:DbContext { /// <summary> /// 重寫(xiě)OnConfiguring方法 /// </summary> /// <param name="optionsBuilder"></param> protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 使用SqlServer數(shù)據(jù)庫(kù),傳遞連接字符串 optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=EFTestDb;User ID=sa;Password=123456;"); base.OnConfiguring(optionsBuilder); } /// <summary> /// 重寫(xiě)OnModelCreating,主要做一些配置 /// 例如設(shè)置生成的表名、主鍵、字符長(zhǎng)度 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(ModelBuilder modelBuilder) { // 設(shè)置生成的表名 modelBuilder.Entity<Student>().ToTable("T_Student"); // 設(shè)置主鍵,可以不設(shè)置,會(huì)默認(rèn)把Id字段當(dāng)成主鍵 modelBuilder.Entity<Student>().HasKey(p => p.Id); // 設(shè)置Name字段的最大長(zhǎng)度 modelBuilder.Entity<Student>().Property("Name").HasMaxLength(32); base.OnModelCreating(modelBuilder); } // DbSet屬性 public DbSet<Student> Students { get; set; } } }
這些工作做好以后,我們就可以用來(lái)生成數(shù)據(jù)庫(kù)表了。
二、生成數(shù)據(jù)庫(kù)表
我們下面以三種方式來(lái)生成數(shù)據(jù)庫(kù)表。首先在控制臺(tái)項(xiàng)目中添加EFCoreTest.Data的引用。
1、代碼生成
我們可以使用代碼來(lái)生成數(shù)據(jù)庫(kù),這樣在程序啟動(dòng)的時(shí)候調(diào)用生成數(shù)據(jù)庫(kù)的代碼就能自動(dòng)生成數(shù)據(jù)庫(kù)了。代碼如下:
using EFCoreTest.Data; using System; namespace EFCoreTest.Con { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); EFCoreDbContext dbContext = new EFCoreDbContext(); bool tfTrue = dbContext.Database.EnsureCreated(); if (tfTrue) { Console.WriteLine("數(shù)據(jù)庫(kù)創(chuàng)建成功!"); } else { Console.WriteLine("數(shù)據(jù)庫(kù)創(chuàng)建失敗!"); } Console.ReadKey(); } } }
運(yùn)行程序:
輸出結(jié)果提示我們創(chuàng)建成功了,在去數(shù)據(jù)庫(kù)里面看看:
我們看到數(shù)據(jù)庫(kù)和表都已經(jīng)生成了,而且表里面的字段屬性是按照我們?cè)诖a里面的設(shè)置生成的。
注意:如果這時(shí)候在程序啟動(dòng)的時(shí)候在去生成數(shù)據(jù)庫(kù)就會(huì)報(bào)錯(cuò):
2、程序包管理器控制臺(tái)遷移
除了使用代碼的方式生成,我們還可以使用數(shù)據(jù)遷移命令來(lái)生成數(shù)據(jù)庫(kù)表,分為下面的三個(gè)步驟。
1、安裝Microsoft.EntityFrameworkCore.Tools包
要使用數(shù)據(jù)遷移命令,首先需要安裝Microsoft.EntityFrameworkCore.Tools包:
2、添加遷移
首先在數(shù)據(jù)上下文類的OnModelCreating()方法里面添加一些種子數(shù)據(jù),這樣生成數(shù)據(jù)庫(kù)以后,表里面就有一些基礎(chǔ)數(shù)據(jù):
using EFCoreTest.Model; using Microsoft.EntityFrameworkCore; namespace EFCoreTest.Data { /// <summary> /// 數(shù)據(jù)上下文類,繼承自DbContext /// </summary> public class EFCoreDbContext:DbContext { /// <summary> /// 重寫(xiě)OnConfiguring方法 /// </summary> /// <param name="optionsBuilder"></param> protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 使用SqlServer數(shù)據(jù)庫(kù),傳遞連接字符串 optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=EFTestDb;User ID=sa;Password=123456;"); base.OnConfiguring(optionsBuilder); } /// <summary> /// 重寫(xiě)OnModelCreating,主要做一些配置 /// 例如設(shè)置生成的表名、主鍵、字符長(zhǎng)度 /// </summary> /// <param name="modelBuilder"></param> protected override void OnModelCreating(ModelBuilder modelBuilder) { // 設(shè)置生成的表名 modelBuilder.Entity<Student>().ToTable("T_Student"); // 設(shè)置主鍵,可以不設(shè)置,會(huì)默認(rèn)把Id字段當(dāng)成主鍵 modelBuilder.Entity<Student>().HasKey(p => p.Id); // 設(shè)置Name字段的最大長(zhǎng)度 modelBuilder.Entity<Student>().Property("Name").HasMaxLength(32); base.OnModelCreating(modelBuilder); // 添加種子數(shù)據(jù) modelBuilder.Entity<Student>().HasData( new Student() { Id = 1, Name = "Tom", Age = 24, Gender = 1 }, new Student() { Id = 2, Name = "Jack", Age = 23, Gender = 2 }, new Student() { Id = 3, Name = "Kevin", Age = 26, Gender = 2 } ); } // DbSet屬性 public DbSet<Student> Students { get; set; } } }
然后使用下面的命令來(lái)添加遷移:
Add-Migration Initial
- Add-Migration:是遷移命令。
- Initial:可以理解成是給這次遷移起的一個(gè)別名,這個(gè)名稱可以任意起,只要保證每次遷移的時(shí)候不重名即可。
如下圖所示:
執(zhí)行這條命令:
我們看到執(zhí)行報(bào)錯(cuò)了,報(bào)錯(cuò)信息提示我們程序的啟動(dòng)項(xiàng)里面也要安裝Mircosoft.EntityFrameworkCore.Tools包,我們?cè)诳刂婆_(tái)程序里面安裝這個(gè)包,然后在執(zhí)行遷移命令:
可以看到,這次執(zhí)行成功了。成功以后會(huì)生成一個(gè)Migrations文件夾,這個(gè)文件夾下面有兩個(gè)類文件:
20200223132908_Init.cs文件是根據(jù)這次遷移生成的文件,里面記錄著這次遷移發(fā)生的改變:
using Microsoft.EntityFrameworkCore.Migrations; namespace EFCoreTest.Data.Migrations { public partial class Init : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "T_Student", columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("SqlServer:Identity", "1, 1"), Name = table.Column<string>(maxLength: 32, nullable: true), Age = table.Column<int>(nullable: false), Gender = table.Column<int>(nullable: false) }, constraints: table => { table.PrimaryKey("PK_T_Student", x => x.Id); }); migrationBuilder.InsertData( table: "T_Student", columns: new[] { "Id", "Age", "Gender", "Name" }, values: new object[] { 1, 24, 1, "Tom" }); migrationBuilder.InsertData( table: "T_Student", columns: new[] { "Id", "Age", "Gender", "Name" }, values: new object[] { 2, 23, 2, "Jack" }); migrationBuilder.InsertData( table: "T_Student", columns: new[] { "Id", "Age", "Gender", "Name" }, values: new object[] { 3, 26, 2, "Kevin" }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "T_Student"); } } }
里面有下面的兩個(gè)方法:
- Up:該方法是要應(yīng)用到數(shù)據(jù)庫(kù)的配置。
- Down:該方法相當(dāng)于是做回滾操作,執(zhí)行這個(gè)方法,可以恢復(fù)到上一個(gè)狀態(tài)。
每進(jìn)行一次遷移就會(huì)生成一個(gè)這樣的文件。
EFCoreDbContextModelSnapshot.cs是根據(jù)在OnModelCreating()方法中的配置生成的文件:
// <auto-generated /> using EFCoreTest.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace EFCoreTest.Data.Migrations { [DbContext(typeof(EFCoreDbContext))] partial class EFCoreDbContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); modelBuilder.Entity("EFCoreTest.Model.Student", b => { b.Property<int>("Id") .ValueGeneratedOnAdd() .HasColumnType("int") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); b.Property<int>("Age") .HasColumnType("int"); b.Property<int>("Gender") .HasColumnType("int"); b.Property<string>("Name") .HasColumnType("nvarchar(32)") .HasMaxLength(32); b.HasKey("Id"); b.ToTable("T_Student"); b.HasData( new { Id = 1, Age = 24, Gender = 1, Name = "Tom" }, new { Id = 2, Age = 23, Gender = 2, Name = "Jack" }, new { Id = 3, Age = 26, Gender = 2, Name = "Kevin" }); }); #pragma warning restore 612, 618 } } }
3、更新數(shù)據(jù)庫(kù)
執(zhí)行完上面的步驟,我們執(zhí)行更新數(shù)據(jù)庫(kù)的命令:
Update-Database
如下圖所示:
執(zhí)行成功,查看數(shù)據(jù)庫(kù)數(shù)據(jù):
T_Student表已經(jīng)生成了,而且表里面也有添加的種子數(shù)據(jù),到此遷移就完成了。
3、命令行遷移
除了上面的兩種方式,還可以使用命令行進(jìn)行遷移,這種方式主要在Web項(xiàng)目里面比較常用。
使用下面的命令安裝:
dotnet tool install --global dotnet-ef
如下圖所示:
安裝完成以后我們?cè)趫?zhí)行命令:
因?yàn)槲冶緳C(jī)的.NET SDK的版本是3.1.1,剛才安裝的dotent-ef的版本是3.1.2,版本不兼容,我們下載最新的.NET SDK,然后安裝。
到此這篇關(guān)于Entity Framework Core使用控制臺(tái)程序生成數(shù)據(jù)庫(kù)表的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Entity?Framework?Core生成數(shù)據(jù)庫(kù)表
- Entity Framework Core對(duì)Web項(xiàng)目生成數(shù)據(jù)庫(kù)表
- .NET Core使用EF生成數(shù)據(jù)庫(kù)出錯(cuò)的解決方法
- Entity Framework使用Code First模式管理數(shù)據(jù)庫(kù)
- 使用EF的Code?First模式操作數(shù)據(jù)庫(kù)
- EFCore 通過(guò)實(shí)體Model生成創(chuàng)建SQL Server數(shù)據(jù)庫(kù)表腳本
- Entity?Framework?Core基于數(shù)據(jù)模型創(chuàng)建數(shù)據(jù)庫(kù)
相關(guān)文章
在asp.net中操作sql server數(shù)據(jù)庫(kù)的一些小技巧
在asp.net中操作sql server數(shù)據(jù)庫(kù)的一些小技巧...2006-09-09[Asp.Net Core]提高開(kāi)發(fā)效率的方法
這篇文章主要介紹了[Asp.Net Core]提高開(kāi)發(fā)效率的方法,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07"虛擬路徑"..."映射到另一個(gè)應(yīng)用程序,這是不允許的!
原因: 用戶控件不能跨虛擬目錄調(diào)用。2008-12-12ASP.NET?Core中MVC模式實(shí)現(xiàn)路由二
這篇文章介紹了ASP.NET?Core中MVC模式實(shí)現(xiàn)路由的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04