以前、少し書いたと思うが、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するテーブルを指定したり、出力先ディレクトリを指定することも可能。