乘風破浪,遇見最佳跨平臺跨終端框架.Net Core/.Net生態 - 適用於Entity Framework Core的命令行(CLI)工具集(Dotnet-EF)

什麼是EFCore CLI

適用於Entity Framework Core的命令行接口(CLI)工具可執行設計時開發任務。例如,可以創建遷移、應用遷移,併爲基於現有數據庫的模型生成代碼。

image

獲取EFCore CLI

https://github.com/TaylorShi/HelloEfCoreCli

安裝EFCore CLI

全局安裝

dotnet tool install --global dotnet-ef

image

更新EFCore CLI

dotnet tool update --global dotnet-ef

image

卸載EFCore CLI

dotnet tool uninstall --global dotnet-ef

image

前置條件

通常使用EFCore CLI之前,我們需要確保項目已經安裝了Microsoft.EntityFrameworkCore.Design,否則將會提示你

Your startup project 'xxxxxxxxxxx.EFSqliteConsole' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again.

終端切換到項目根目錄,使用命令行安裝它

https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Design

dotnet add package Microsoft.EntityFrameworkCore.Design

如果是Net Core 3.1項目,最新的版本無法兼容,可以追加版本號參數--version 5.0.17

驗證EFCore CLI

dotnet ef

image

管理遷移

建立示例項目(Sqlite)

依賴包

https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Sqlite

dotnet add package Microsoft.EntityFrameworkCore.Sqlite

如果是Net Core 3.1項目,最新的版本無法兼容,可以追加版本號參數--version 5.0.17

建立示例領域

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; } = new List<Post>();
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

建立示例DbContext

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    public string DbPath { get; }

    public BloggingContext()
    {
        var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = Environment.GetFolderPath(folder);
        DbPath = System.IO.Path.Join(path, "blogging.db");
    }

    // The following configures EF to create a Sqlite database file in the
    // special "local" folder for your platform.
    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseSqlite($"Data Source={DbPath}");
}

添加初始化遷移

dotnet ef migrations add $name

例如:

dotnet ef migrations add InitCreate

image

這個動作會創建一些遷移用的.cs文件,默認存放在項目根目錄的Migrations文件夾中。

image

可選項

  • 如果要修改這個目錄路徑,可以使用參數:--output-dir|-o指定。
  • 如果要指定生成類的命名空間,可以使用參數:--namespace|-n指定。

列出可用的遷移

dotnet ef migrations list

image

可選項

  • 如果要指定用於連接到數據庫的連接字符串,可以使用參數:--connection指定,默認爲AddDbContextOnConfiguring中指定的值。
  • 如果要指定不要連接到數據庫,可以使用參數:--no-connect指定。

回退上次的遷移

刪除上一次遷移,回退爲上一次遷移所做的代碼更改。

dotnet ef migrations remove

image

可選項

  • 如果要如果連接到數據庫時出錯,則繼續僅回退到代碼更改,可以使用參數:--force|-f指定。

從遷移生成SQL腳本

我們可以基於遷移得到SQL腳本

dotnet ef migrations script $fromIndex $name

這裏$fromIndex默認值就是0

可選項

  • 如果要指定生成腳本的文件路徑,可以使用參數:--output|-o指定。
  • 如果要生成可在任何遷移時用於數據庫的腳本,可以使用參數:--idempotent|-i指定。
  • 不要生成SQL事務語句,可以使用參數:--no-transactions指定。

例如從InitCreate的首次遷移前到它自身包括的SQL腳本

dotnet ef migrations script 0 InitCreate

image

這時候我們給Blog領域模型增加一個Title字段

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public string Title { get; set; }

    public List<Post> Posts { get; } = new List<Post>();
}

並且我們創建一個新的遷移UpdateBlogTitle

dotnet ef migrations add UpdateBlogTitle

image

這個時候,按道理就應該有兩個遷移了,那麼從InitCreate之後遷移的所有SQL腳本,就能夠生成第二次UpdateBlogTitle的SQL腳本了

dotnet ef migrations script InitCreate

image

確實結果是這樣的。

創建可執行文件更新數據庫

dotnet ef migrations bundle

需要 >=Entity Framework Core 6.0.0

可選項

  • 如果要指定要創建的可執行文件的路徑,可以使用參數:--output|-o指定。
  • 如果要覆蓋現有文件,可以使用參數:--force|-f指定
  • 如果要同時綁定.NET 運行時,因此不需要在計算機上安裝它,可以使用參數:--self-contained指定
  • 如果要要綁定的目標運行時,可以使用參數:--target-runtime指定

管理上下文

獲取DbContext信息

dotnet ef dbcontext info

image

列出可用DbContext

dotnet ef dbcontext list

image

生成DbContext優化模型

dotnet ef dbcontext optimize

需要 >=Entity Framework Core 6.0.0

根據數據庫生成代碼

dotnet ef dbcontext scaffold $Connection $Provider

其中

  • $Connection,用於連接到數據庫的連接字符串。
  • $Provider,要使用的提供程序,通常,這是NuGet包的名稱,例如Microsoft.EntityFrameworkCore.SqlServer

可選項

  • 如果要使用屬性配置模型,可以使用參數:--data-annotations|-d指定。
  • 如果要指定生成的DbContext類的名稱,可以使用參數:--context指定。
  • 如果要指定放置DbContext類文件的目錄,可以使用參數:--context-dir指定。
  • 如果要指定生成的DbContext類的命名空間,可以使用參數:--context-namespace指定。
  • 如果要覆蓋現有文件,可以使用參數:--force|-f指定。
  • 如果要指定放置實體類文件的目錄,可以使用參數:--output-dir|-o指定。
  • 如果要指定所有生成的類的命名空間,可以使用參數:--namespace|-n指定。
  • 如果要指定生成實體類型的表的架構,可以使用參數:--schema指定。
  • 如果要指定爲其生成實體類型的表,可以使用參數:--table|-t指定。
  • 如果要使用與數據庫中顯示的名稱完全相同的表和列名,可以使用參數:--use-database-names指定。
  • 如果要禁止在生成的DbContext類中生成OnConfiguring方法,可以使用參數:--no-onconfiguring指定。
  • 請勿使用複數化程序,可以使用參數:--no-pluralize指定。

例如

dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models
dotnet ef dbcontext scaffold "DataSource=C:\Users\TaylorShi\AppData\Local\blogging.db" Microsoft.EntityFrameworkCore.Sqlite -o Models

image

image

dotnet ef dbcontext scaffold "DataSource=C:\Users\TaylorShi\AppData\Local\blogging.db" Microsoft.EntityFrameworkCore.Sqlite -o Models -t Blogs -t Posts --context-dir Context -c BlogContext --context-namespace TeslaOrder.EFSqliteConsole

image

image

public partial class BlogContext : DbContext
{
    public BlogContext()
    {
    }

    public BlogContext(DbContextOptions<BlogContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Blog> Blogs { get; set; }
    public virtual DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
            optionsBuilder.UseSqlite("DataSource=C:\\Users\\TaylorShi\\AppData\\Local\\blogging.db");
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>(entity =>
        {
            entity.HasIndex(e => e.BlogId, "IX_Posts_BlogId");

            entity.HasOne(d => d.Blog)
                .WithMany(p => p.Posts)
                .HasForeignKey(d => d.BlogId);
        });

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

從DbContext生成SQL腳本

dotnet ef dbcontext script

可選項

  • 如果要指定生成的SQL腳本文件,可以使用參數:--output|-o指定。
  • 如果要指定DbContext,可以使用參數:--context|-c指定。

image

管理數據庫

根據遷移更新數據庫

dotnet ef database update $name

其中$name可以指定遷移的遷移名稱。

可選項

  • 如果要指定用於連接到數據庫的連接字符串,可以使用參數:--connection指定,默認爲AddDbContextOnConfiguring中指定的值。

例如,不帶參數代表開始首次遷移之前並會還原所有遷移

dotnet ef database update

image

image

dotnet ef database update 20221031043138_UpdateBlogName

image

另外>=Entity Framework Core 5.0.0還支持將其他參數傳遞到Program.CreateHostBuilder

dotnet ef database update -- --environment Production

其中--之後所有內容都會被視爲參數,它將轉發給應用去處理。

刪除數據庫

dotnet ef database drop

可選項

  • 如果不需要確認,直接刪除,可以使用參數:--force|-f指定。
  • 如果顯示要刪除的數據庫,但不刪除它,可以使用參數:--dry-run指定。

image

參考

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