1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Asp-Net-Core開發(fā)筆記:快速在已有項目中引入EFCore

        共 6866字,需瀏覽 14分鐘

         ·

        2023-10-13 17:41

        1前言

        很多項目一開始選型的時候沒有選擇EFCore,不過EFCore確實好用,也許由于種種原因后面還是需要用到,這時候引入EFCore也很方便。

        本文以 StarBlog 為例,StarBlog 目前使用的 ORM 是 FreeSQL ,引入 EFCore 對我來說最大的好處是支持多個數(shù)據(jù)庫,如果是 FreeSQL 的話,服務(wù)注冊的時候是單例模式,只能連接一個數(shù)據(jù)庫,如果需要使用 FreeSQL 同時連接多個數(shù)據(jù)庫,需要自行做一些額外的工作。

        要實現(xiàn)的效果是:把訪問記錄單獨使用一個數(shù)據(jù)庫來存儲,并且使用 EFCore 管理。

        2安裝工具

        首先安裝 EFCore 的 cli 工具

        dotnet tool install --global dotnet-ef

        3項目架構(gòu)

        先來回顧一下項目架構(gòu):基于.NetCore開發(fā)博客項目 StarBlog - (2) 環(huán)境準備和創(chuàng)建項目

        StarBlog
        ├── StarBlog.Contrib
        ├── StarBlog.Data
        ├── StarBlog.Migrate
        ├── StarBlog.Web
        └── StarBlog.sln

        為了解耦,和數(shù)據(jù)有關(guān)的代碼在 StarBlog.Data 項目下,因此引入 EFCore 只需要在 StarBlog.Data 這個項目中添加依賴即可。

        4添加依賴

        StarBlog.Data 項目中添加以下三個依賴

        • Microsoft.EntityFrameworkCore
        • Microsoft.EntityFrameworkCore.Sqlite
        • Microsoft.EntityFrameworkCore.Tools

        EFCore 對 SQLite 的支持很弱(根本原因是微軟提供的 SQLite 驅(qū)動功能太少),所以只適合在本地開發(fā)玩玩,實際部署還是得切換成 C/S 架構(gòu)的數(shù)據(jù)庫(PgSQL/MySQL/SQL Server)才行。

        添加后項目的 .csproj 文件新增的依賴類似這樣

        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.18" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.18" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.18">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>

        目前 StarBlog 還在使用 .Net6 所以我添加的 EFCore 是 6.x 版本,等后續(xù) .Net8 正式版發(fā)布之后,我會把這個項目升級到 .Net8

        5創(chuàng)建 DbContext

        DbContext 是 EFCore 與數(shù)據(jù)庫交互的入口,一般一個數(shù)據(jù)庫對應(yīng)一個。

        現(xiàn)在來 StarBlog.Data 項目下創(chuàng)建一個。

        using Microsoft.EntityFrameworkCore;
        using StarBlog.Data.Models;

        namespace StarBlog.Data;

        public class AppDbContext : DbContext {
          public DbSet<VisitRecord> VisitRecords { getset; }
          
          public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
        }

        因為只需要讓 EFCore 管理訪問記錄,所以只需要一個 DbSet

        6實體類配置

        然后來創(chuàng)建個配置,雖然也可以用 Data Annotation 來配置,但 EFCore 推薦使用 Fluent Config 方式來配置數(shù)據(jù)表和字段。

        創(chuàng)建 StarBlog.Data/Config/VisitRecordConfig.cs 文件

        public class VisitRecordConfig : IEntityTypeConfiguration<VisitRecord> {
          public void Configure(EntityTypeBuilder<VisitRecord> builder) {
            builder.ToTable("visit_record");
            builder.HasKey(e => e.Id);
            builder.Property(e => e.Ip).HasMaxLength(64);
            builder.Property(e => e.RequestPath).HasMaxLength(2048);
            builder.Property(e => e.RequestQueryString).HasMaxLength(2048);
            builder.Property(e => e.RequestMethod).HasMaxLength(10);
            builder.Property(e => e.UserAgent).HasMaxLength(1024);
          }
        }

        主要是配置了主鍵和各個字段的長度。

        數(shù)據(jù)類型這塊 EFCore 會自動映射,具體請參考官方文檔。

        7主鍵類型選擇

        這里插播一下題外話,關(guān)于主鍵類型應(yīng)該如何選擇。

        目前主要有幾種方式:

        • 自增
        • GUID
        • 自增+GUID
        • Hi/Lo

        這幾種方式各有優(yōu)劣。

        • 自增的好處是簡單,缺點是在數(shù)據(jù)庫遷移或者分布式系統(tǒng)中容易出問題,而且高并發(fā)時插入性能較差。
        • GUID好處也是簡單方便,而且也適用于分布式系統(tǒng);MySQL的InnoDB引擎強制主鍵使用聚集索引,導(dǎo)致新插入的每條數(shù)據(jù)都要經(jīng)歷查找合適插入位置的過程,在數(shù)據(jù)量大的時候插入性能很差。
        • 自增+GUID是把自增字段作為物理主鍵,GUID作為邏輯主鍵,可以在一定程度上解決上述兩種方式的問題。
        • Hi/Lo可以優(yōu)化自增列的性能,但只有部分數(shù)據(jù)庫支持,比如SQL Server,其他的數(shù)據(jù)庫暫時還沒研究。

        8DesignTime 配置

        因為我們的項目是把 AspNetCore 和數(shù)據(jù)分離的,所以需要一個 DesignTime 配置來讓 EFCore 知道如何執(zhí)行遷移。

        StarBlog.Data 中創(chuàng)建 AppDesignTimeDbContextFactory.cs 文件

        public class AppDesignTimeDbContextFactory : IDesignTimeDbContextFactory<AppDbContext> {
          public AppDbContext CreateDbContext(string[] args) {
            var builder = new DbContextOptionsBuilder<AppDbContext>();

            var connStr = Environment.GetEnvironmentVariable("CONNECTION_STRING");
            if (connStr == null) {
              var dbpath = Path.Combine(Environment.CurrentDirectory, "app.log.db");
              connStr = $"Data Source={dbpath};";
            }

            builder.UseSqlite(connStr);
            return new AppDbContext(builder.Options);
          }
        }

        這里從環(huán)境變量讀取數(shù)據(jù)庫連接字符串,如果讀不到就使用默認的數(shù)據(jù)庫文件。

        9數(shù)據(jù)庫遷移

        這塊主要是使用兩組命令

        • migrations - 用于監(jiān)控數(shù)據(jù)庫的修改
        • database - 將修改同步到數(shù)據(jù)庫里

        cd 到 StarBlog.Data 目錄下,執(zhí)行

        dotnet ef migrations add InitialCreate -o Migrations 

        之后可以看到 Migrations 目錄下生成了遷移的代碼

        如果需要指定數(shù)據(jù)庫文件,可以設(shè)置環(huán)境變量。

        Windows的使用:

        set CONNECTION_STRING = "Data Source=app.db;"

        Linux的也差不多,把 set 換成 export

        export CONNECTION_STRING = "Data Source=app.db;"

        運行以下命令同步到數(shù)據(jù)庫

        dotnet ef database update

        執(zhí)行之后就會在 StarBlog.Data 下生成 SQLite 數(shù)據(jù)庫文件。

        10在AspNetCore項目里集成EFCore

        先把數(shù)據(jù)庫連接字符串寫到配置文件 appsettings.json

        {
          "ConnectionStrings": {
            "SQLite""Data Source=app.db;Synchronous=Off;Cache Size=5000;",
            "SQLite-Log""Data Source=app.log.db;"
          }
        }

        Program.cs 里注冊服務(wù)

        builder.Services.AddDbContext<AppDbContext>(options => {
          options.UseSqlite(builder.Configuration.GetConnectionString("SQLite-Log"));
        });

        搞定~

        11db-first

        從已有數(shù)據(jù)庫生成實體類,一般新項目不推薦這種開發(fā)方式,不過在舊項目上使用還是比較方便的,EFCore 的 cli tool 也提供很豐富的代碼生成功能。

        這里提供一下例子:

        • 使用 PostgreSql 數(shù)據(jù)庫,要把其中 pe_shit_data 庫的所有表生成實體類
        • 生成的 DbContext 類名為 ShitDbContext
        • DbContext 類的命名空間為 PE.Data
        • 實體類放在 ShitModels 目錄下,命名空間為 PE.Data.ShitModels

        命令如下

        dotnet ef dbcontext scaffold `
        "Host=cuc.dou3.net;Database=pe_shit_data;Username=postgres;Password=passw0rd" `
        Npgsql.EntityFrameworkCore.PostgreSQL `
        -f `
        -c ShitDbContext `
        --context-dir . `
        --context-namespace PE.Data `
        -o ShitModels `
        --namespace PE.Data.ShitModels `

        這個是 powershell 的命令,如果是 Linux 環(huán)境,把每一行命令末尾的反引號換成 \ 即可。

        12參考資料

        • https://learn.microsoft.com/en-us/ef/core/cli/dotnet
        • https://learn.microsoft.com/zh-cn/ef/core/managing-schemas/scaffolding


        瀏覽 147
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日本亚洲色大成网站www久久 | 免费看一级黄色大片 | 精品一区二区成人免费视频 | 亚洲AV成人无码久久精品巨臀 | 中文字幕日韩在线播放 | 国产一级a毛一级a看高清视频 | 国产精品美女久久久久久久网站 | 熟女内射 | 亚洲大逼色 | 人妻无码在线视频 |