きなこもち.net

.NET Framework × UiPath,Orchestrator × Azure × AWS × Angularなどの忘備録

EF Core Power Tools × "Reverse Engineer"機能 × How to use

overview

使い方がわからなかったので調べてみた系の記事。

Basic options

Reverse Engineer機能で始めに設定しないといけないオプションたち。Advanced Optionが別にあったので、こっちはBasicとしてまとめたが、画面にはBasicとは書かれていない。 ★印は、概要+動作確認をした項目の意。

  • Context name
    • 生成される DB Context の名前
  • Namespace
  • Entity Types path - Option

    • 生成される Entity を格納するディレクトリ名。あらかじめ作成しておく必要はない。なければ自動で作られる。
  • What to generate

    • Entity Types and DbContext
    • DB Context   Only
    • Entity Types Only
  • Naming

    • ★ pluralize or singularize generated object names
      • 生成されたオブジェクト名を複数化または単数化する
    • ★ Use table and column names directly from database
      • データベースから直接テーブル名と列名を使用する
  • ★ Use DataAnnotation attributes to configure the model DataAnnotation

    • 属性を使用してモデルを構成する。指定しない場合は、Configure メソッド内で定義される。
  • Customize code using templates
    • 指定したテンプレートを使って生成されるコードをカスタマイズする
  • Include connection string in generated code
    • 生成されたコード(dbcontext class - OnConfiguring method)に今回利用した接続文字列を含める
  • Install the EF Code Provider pacakge in the proje ct
    • 対象のプロジェクトに EF Code Provider(Postgres の場合は、Npgsql Provider)の Pacakge をインストールする。

Advanced options

  • Code generation

    • ★ Remove default DbContext constructor
      • DbContext のデフォルトコンストラクタを生成しない
    • Remove SQL default from bool columns
      • ブール列から SQL デフォルトを削除する
    • ★ Use nullable reference types(experimental)
      • Null 許容の参照型を利用する
    • ★ Use many to many entity (EF Core 6 and later)
      • 多対多の Entity を利用する
    • Always include all database objects
      • 常にすべてのデータベースオブジェクトを有効にする
  • File layout

    • Split DbContext into Configuration classes (preview)
      • DbContext と Configuration クラスを分ける。
    • Use schema folder separation (experimental)
    • Use schema namespaces separation (experimental)
      • EntityTypes sub-namespace - optional
      • DbContext path - optional
      • DbContext sub-namespace - optional
  • Mapping

    • Map spatial types
    • Map hierarchyid
    • Map DateOnly and TimeOnly
    • Map Noda Time types
    • Use EF6 plurlizer
      • EF6 plurlizer => テーブル名を複数形、単数形にする

わかりにくかったところを中心に・・・

pluralize or singularize generated object names

コメントアウト= pluralize or singularize generated object names 有効 複数形のほうが適切な場合にプロパティ名が複数形になる。FilmActor -> FilmActors.

namespace WorkerService1.EntityModels.publicSchema
{
    public partial class Actor
    {
        public Actor()
        {
            FilmActor = new HashSet<FilmActor>();
            //FilmActors = new HashSet<FilmActor>();
        }

        public int ActorId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime LastUpdate { get; set; }

        public virtual ICollection<FilmActor> FilmActor { get; set; }
        //public virtual ICollection<FilmActor> FilmActors { get; set; }
    }
}

Use table and column names directly from database

ファイル名は、Actor だが、クラス名他が DB と同じ名前になる。

namespace WorkerService1.EntityModels.publicSchema
{
    public partial class actor
    {
        public actor()
        {
            film_actor = new HashSet<film_actor>();
        }

        public int actor_id { get; set; }
        public string first_name { get; set; }
        public string last_name { get; set; }
        public DateTime last_update { get; set; }

        public virtual ICollection<film_actor> film_actor { get; set; }
    }
}

Remove SQL default from bool columns

DBContext - Configure method で、HasDefaultValueSql を使って設定される処理がなくなる。この場合、どこでも設定されないことになる。bool の初期値は false なので、このままいくと、Staff の初期値が false になってしまうので注意が必要。 例:Staff - active column (type=bool)

  • Not null
  • Default Value = True
//コメントアウト=オプションありの場合。
public void Configure(EntityTypeBuilder<Staff> entity)
{
    entity.Property(e => e.Active)
        .IsRequired()
        .HasColumnName("active")
        .HasDefaultValueSql("true");
    //entity.Property(e => e.Active).HasColumnName("active");
}

namespace WorkerService1.EntityModels.publicSchema
{
    public partial class Staff
    {
        public int StaffId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int AddressId { get; set; }
        public string Email { get; set; }
        public int StoreId { get; set; }
        public bool? Active { get; set; }
        //public bool Active { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public DateTime LastUpdate { get; set; }
        public byte[] Picture { get; set; }
    }
}

Use nullable reference types(experimental)

勉強不足で始めて知った。
! (null 免除) 演算子 (C# リファレンス)によると、
単項の接尾辞 ! 演算子は null 免除 (または null 抑制) 演算子です。 Null 許容注釈コンテキストが有効な場合、null 免除演算子を使って、前の式のすべての Null 許容警告を抑制します。 単項の接頭辞 ! 演算子は、論理否定演算子です。 null 免除演算子は実行時には影響を与えません。

null 免除演算子は実行時には影響を与えません。とのこと。 オプションを有効にすると、以下のように免除演算子が追加される。コーディングチェックによる警告を抑制したい場合は便利。

public virtual Posts Posts { get; set; } = null!;

Use many to many entity (EF Core 6 and later)

many-to-manyの説明資料のテーブル定義を使って、生成される Entity の違いを確認した。

Use may to may entity をOnにした場合

数が多いので、Tags クラスを例に確認する。Tags クラスには、PostTag のプロパティが設定される。

    public partial class Tags
    {
        public Tags()
        {
            PostTag = new HashSet<PostTag>();
        }

        public int Id { get; set; }

        public virtual ICollection<PostTag> PostTag { get; set; }
    }

Use may to may entity をOffにした場合

PostTag のプロパティの代わりに、Post クラスのコレクションが設定されたプロパティが定義される。この時、PostTag のクラス定義は作成されなかった。
= EF Core によって、結合エンティティ型を隠し、多対多の関係を EF Core 内部(バックグラウンド)で管理できるようになる。
EF PowerTool のこのオプションは、Many to Many を明示的に実装するかどうかを切り替えることができるオプションで、On にした場合は、EF Core   6 より前の EF Core で多対多を管理してきた方式になるようだ。

    public partial class Tags
    {
        public Tags()
        {
            Posts = new HashSet<Posts>();
        }

        public int Id { get; set; }

        public virtual ICollection<Posts> Posts { get; set; }
    }

ref ) https://github.com/ErikEJ/EFCorePowerTools/issues/1184

ref

wiki many to many