Net5 控制檯應用程序引入EFCore+CodeFirst

十年河東,十年河西。莫欺少年窮

學無止境,精益求精

最近再看Net5相關視頻,看的過程中就想把看到的知識通過博客展示出來,因此就有了這篇博客

之前項目中用的DbFirst ,本篇開啓CodeFirst,按照微軟官方提供的說法,是希望大家都用CodeFirst

1、CodeFirst

1.1、新建控制檯項目並引入如下程序集

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools 

1.2、編寫實體

實體對應的是數據庫的表

    public class Book
    {
        public long id { get; set; }
        [Description("書的名稱")]
        public string Title { get; set; }
        public DateTime Pubdate { get; set; }
        public double Price { get; set; }
    }
    public class Person
    {
        public long id { get; set; }
        [Description("姓名")]
        public string Name { get; set; }
        public string Age { get; set; } 
        public string Address { get; set; }
    }
View Code

1.3、綁定實體和數據表的關係

    public class BookConfig : IEntityTypeConfiguration<Book>
    {
        public void Configure(EntityTypeBuilder<Book> builder)
        {
            builder.ToTable("T_Books");
        }
    }

    public class PersonConfig : IEntityTypeConfiguration<Person>
    {
        public void Configure(EntityTypeBuilder<Person> builder)
        {
            builder.ToTable("T_Persons");
            builder.Property("Name").HasMaxLength(50).IsRequired(true).HasComment("我是字段備註:姓名");
        }
    }
View Code

意味着Book實體對應的表爲  T_Books

 builder.Property 聲明字段的一些規則,例如長度最大爲50【HasMaxLength(50)】、字段爲非空字段【IsRequired(true)】、設定字段備註【HasComment】等

            // builder.ToView<Book>("視圖名稱"); //綁定視圖的模式
            //builder.Ignore(A => A.Pubdate);//Pubdate 字段是實體中的字段,但不會出現在Table中,例如默寫通過計算得出的列或者屬性
            //builder.Property("Name").HasColumnName("BookName"); //配置列名  在數據表中會展示爲BookName
            // builder.Property("Name").HasColumnType("varcahr(200)"); //配置列名的數據類型 改變默認的Varchar(MAX) 及 改變數據庫的 NVVARCHAR(MAX) ,不存中文時用這個

            //builder.Property("Name").HasDefaultValue("書"); 默認值
            //builder.HasKey(A => A.Title);//修改默認主鍵配置  主鍵爲 Title
            //builder.HasIndex(A => A.Price);//設置價格列爲索引
           // builder.HasIndex(A => new { A.Price, A.Pubdate });//設置複合索引
            builder.HasIndex(A => A.Price).IsUnique();//設置唯一索引

除了上述的方法外,我們還可以通過數據註解的方式完成字段最大長度設定、是否能爲Null等設置,例如:

    [Table("T_Cats")]
    public class Cat
    { 
        //當遇到 Int、long、ShortInt、Guid類型時,根據約定,該字段會被設置爲主鍵
        public Guid catId { get; set; }
        [Required]
        [MaxLength(50)] 
        public string catName { get; set; }

        [MaxLength(50)]
        public string sex { get; set; }
    }

這種方式雖說簡單,但,還是建議大家使用IEntityTypeConfiguration<>的方式進行綁定

例如有這麼個變態需求,當使用MySQL數據時,希望在數據庫中表名爲M_Cats,當在SQLServer數據庫中是希望表名爲T_Cats,那麼如果你使用數據註解的方式就無法完成這個工作,使用IEntityTypeConfiguration<>的方式則可以在void Configure(EntityTypeBuilder<Person> builder)方法中寫相關的邏輯代碼。

1.4、創建數據庫上下文

    public class wechatDbContext : DbContext
    {
        public DbSet<Book> Books { get; set; }
        public DbSet<Person> Persons { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseSqlServer("Data Source=LAPTOP-84R6S0FB;Initial Catalog=wechat;Integrated Security=True");

        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //從當前程序集命名空間加載所有的IEntityTypeConfiguration
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
View Code

OnConfiguring 方法初始化數據庫鏈接字符串

OnModelCreating   從當前程序集命名空間加載所有的IEntityTypeConfiguration綁定的實體

1.5、通過程序包控制檯,生成數據庫

Add-Migration initDb

--

Update-Database

Add-Migration 的語法爲 Add-Migration + 備註,每次備註不允許一樣

Update_DataBase 生成或更新數據庫

當然,如果在實際編碼中修改字段的長度、字段類型,新增字段、刪除字段等操作後,需要執行 Add-Migration 和 Update-DataBase ,執行後數據庫纔會做出響應的改變。

1.6、簡單測試

由於DbContext 繼承了 IDisposable 、因此在編程時,我們需要使用Using ,這樣做是爲了能夠及時的釋放佔用的資源。

 

 簡單測試如下:

using System;
using System.Linq;
using System.Threading.Tasks;

namespace EfCore
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            var tsk_1 = add();
            var tsk_2 = update(await tsk_1);
            var tsk_3 = delete(await tsk_1); 
            await tsk_2;
            await tsk_3;
            Console.WriteLine("執行完畢");
            Console.Read();
        }

        static  async Task<int> add()
        {
            using (wechatDbContext context = new wechatDbContext())
            {
                Book bok = new Book();  
                bok.Title = "鋼鐵是怎麼練成的";
                bok.Price = 180;
                bok.Pubdate = DateTime.Now;
                context.Books.Add(bok);
                Book bok2 = new Book();
                bok2.Title = "平凡的世界";
                bok2.Price = 110;
                bok2.Pubdate = DateTime.Now;
                context.Books.Add(bok2);
                return  await context.SaveChangesAsync();
            }
        }

        static async Task update(int addnum)
        {
            using (wechatDbContext context = new wechatDbContext())
            {
                var ef = context.Books.Where(A => A.Title == "平凡的世界").FirstOrDefault();
                ef.Price = 122;
                await context.SaveChangesAsync();
            }
        }

        static async Task delete(int addNum)
        {
            using (wechatDbContext context = new wechatDbContext())
            {
                var ef = context.Books.Where(A => A.Title == "鋼鐵是怎麼練成的").FirstOrDefault();
                context.Books.Remove(ef);
                await context.SaveChangesAsync();
            }
        }

    }
}
View Code

@天才臥龍的bolero

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章