EF CoreによるDBからのEntity作成(Scaffolding)

以前、少し書いたと思うが、Entity Framework Coreを使用して、既存のDBからDbContextクラスとEntityクラスを作成する事が可能である。

例えば以下のようなテーブルを含むDBがあった場合、どのようなEntityおよびDbContextとなるか試してみよう。

データベース(SQLite)

CREATE TABLE Person(
  Id int atuoincrement,
  Name nvarchar(50),
  primary key (Id)
);
CREATE TABLE MailAddress(
  Address nvarchar(100),
  DisplayName nvarchar(50),
  PersonId int,
  primary key(Address),
  foreign key(PersonId) references Person(Id)
);

プロジェクトには下記のパッケージを追加する

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameoworkCore.Design
  • Microsoft.EntityFrameworkCore.Sqlite
  • Microsoft.EntityFrameowrkCore.Sqlite.Design

下記コマンドを実行して、DbContextとEntityを作成
(scaffoldのパラメータは「接続文字列」と「データプロバイダ」)

$ dotnet ef dbcontext scaffold "Data Source=SQLiteTest.db" Microsoft.EntityFrameworkCore.Sqlite

出来上がったDbContextとEntity

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace SQLiteTest
{
    public partial class SQLiteTestContext : DbContext
    {
        public SQLiteTestContext()
        {
        }

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

        public virtual DbSet<MailAddress> MailAddress { get; set; }
        public virtual DbSet<Person> Person { 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. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
                optionsBuilder.UseSqlite("Data Source=SQLiteTest.db");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<MailAddress>(entity =>
            {
                entity.HasKey(e => e.Address);

                entity.Property(e => e.Address).HasColumnType("nvarchar(100)");

                entity.Property(e => e.DisplayName).HasColumnType("nvarchar(50)");

                entity.Property(e => e.PersonId).HasColumnType("int");

                entity.HasOne(d => d.Person)
                    .WithMany(p => p.MailAddress)
                    .HasForeignKey(d => d.PersonId);
            });

            modelBuilder.Entity<Person>(entity =>
            {
                entity.Property(e => e.Id)
                    .HasColumnType("int atuoincrement")
                    .ValueGeneratedNever();

                entity.Property(e => e.Name).HasColumnType("nvarchar(50)");
            });

            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}
using System;
using System.Collections.Generic;

namespace SQLiteTest
{
    public partial class Person
    {
        public Person()
        {
            MailAddress = new HashSet<MailAddress>();
        }

        public long Id { get; set; }
        public string Name { get; set; }

        public virtual ICollection<MailAddress> MailAddress { get; set; }
    }
}
using System;
using System.Collections.Generic;

namespace SQLiteTest
{
    public partial class MailAddress
    {
        public string Address { get; set; }
        public string DisplayName { get; set; }
        public long? PersonId { get; set; }

        public virtual Person Person { get; set; }
    }
}

とまあ、こんな感じでDBからDbContextとEntityを作成することができる。
接続文字列が埋め込みになっているので、この部分はappsettings.json等から取得するように変更した方が良いだろう。

なお、scaffoldのオプションで、scaffoldするテーブルを指定したり、出力先ディレクトリを指定することも可能。

takezou について

ソフトウェア開発会社(ITと言う言葉は大嫌い)で働く、元技術者。 未だに、社内システム位は作ってますが・・・ プログラミング言語はC#が好き。
カテゴリー: C#, dotnetcore, Entity Framework, 技術系 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください