sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

PlanetScale - SELECT INSERT UPDATE を実行する (Entity Framework)

f:id:shikaku_sh:20220122172122p:plain

PlanetScale (MySQL 互換) の基本的な DML (select, insert, update) を C# の環境で実行してみた。今回は、Entity Framework を介してデータ操作をしてみる。

なお、EF を使わないやり方はこっち

接続文字列のパラメーターは、NuGet から「DotNetEnv」を使って隠しています。

DotNetEnv.Env.Load(".env");

var server = DotNetEnv.Env.GetString("SERVER");
var user = DotNetEnv.Env.GetString("USER");
var password = DotNetEnv.Env.GetString("PASSWORD");
var database = DotNetEnv.Env.GetString("DATABASE");
var port = DotNetEnv.Env.GetString("PORT");
var ssl = DotNetEnv.Env.GetString("SSLMODE");

var connectionString = $"server={server};user={user};database={database};port={port};password={password};SslMode={ssl}";

MySqlContext.ConnectionString = connectionString;

初期化

Entity Framework を利用するときは、App.configapp.config.transformADO.NET のプロバイダーの初期化などをすると思います。

コードから直接書いた一例は、こんな感じ:

public class MySqlConfiguration : DbConfiguration
{
    public MySqlConfiguration()
    {
        SetDefaultConnectionFactory(new MySqlConnectionFactory());

        // MySql.Data.MySqlClient
        string name = MySql.Data.EntityFramework.MySqlProviderInvariantName.ProviderName;

        SetProviderFactory(name, new MySql.Data.MySqlClient.MySqlClientFactory());
        SetProviderServices(name, new MySql.Data.MySqlClient.MySqlProviderServices());
    }
}

App ファイルにするのもよいですが、コードで書いておくとデータベース自体の切替なんかに対応しやすいかもしれないです。初期化のあと DbContext を作成します。

Users テーブル(サンプル)を開く DbContext の一例。

public class DbContextBase : DbContext
{
    public DbSet<Users> Users => Set<Users>();

    //public DbSet<Users> Users { get; set; } = null!;

    public DbContextBase(DbConnection connection) : base (connection, true)
    {

    }
}
[DebuggerDisplay("接続文字列:{ConnectionString}")]
public class MySqlContext : DbContextBase
{
    public static string ConnectionString { get; set; } = "";

    public MySqlContext() : base(new MySqlConnection(ConnectionString))
    {
    }
}
[Table("users")]
public class Users
{
    [Key]
    [Column("id")]
    public int? Id { get; set; }

    [Column("email")]
    public string Email { get; set; } = "";

    [Column("first_name")]
    public string FirstName { get; set; } = "";

    [Column("last_name")]
    public string LastName { get; set; } = "";
}

カラムではない拡張等が目的のプロパティは NotMapped をつける。

あとは各種 DML で操作してみるけど、実際の前準備は以下のとおり。MySqlConfiguration は(EF を利用するタイミングで)自動的に呼び出されるので気にしなくてよいです。

SELECT

SELECT 文を実行する例はこんな感じ。

private void SelectEF()
{
    using (var context = new MySqlContext())
    {
        foreach (var u in context.Users)
        {
            Console.WriteLine($"id={u.Id}, email={u.Email}");
        }
    }
}

INSERT

INSERT 文を実行する例はこんな感じ。

private void InsertEF()
{
    var newUser = new Users
    {
        Email = "EF@aa.bb",
        FirstName = "EF_firstname",
        LastName = "EF_lastname",
    };

    using (var context = new MySqlContext())
    {
        context.Users.Add(newUser);
        context.SaveChanges();
    }
}

User は id を持っています。割り振られた id は、SaveChanges() を実行したあとにパラメーターの値が更新されています。忘れがち。

f:id:shikaku_sh:20220204105031p:plain:w600 f:id:shikaku_sh:20220204105040p:plain:w600

UPDATE

UPDATE 文を実行する例はこんな感じ。

private void UpdateEF()
{
    using (var context = new MySqlContext())
    {
        var user = context.Users.SingleOrDefault(p => p.Id == 1);

        if (user == null) return;

        user.Email = "update@mail.com";
        user.FirstName = "update.name1";
        user.LastName = "update.name2";

        context.SaveChanges();
    }
}

サンプル

GitHub にサンプルを公開しています。

Entity Framework を利用したほうが、ほとんどのケースでは正解だと思います。おおきな理由は実行しなくてもコンパイルエラーのチェックをできる箇所が増えるから。

Command からだと文字列に値をセットするような処理は、実行するまでエラーチェックがあまりできなかったりします。Entity Framework だとクラスと変数に値を直接設定できるので安心。

参考