VS Code+.Netでアプリを作る(No.11):MariaDBに接続するコンソールアプリ作成時にusing method 'mysql_native_password' failedで失敗
これを参考にコンソールアプリでMySQLへ接続する。
外部接続を許可する。
cat > /etc/mysql/conf.d/mysql.cnf << EOF [mysqld] bind-address = 0.0.0.0 ignore-db-dir = lost+found EOF
ユーザー作成と、ユーザーからの内部、外部接続を許可しておく。
$ sudo mysql -u root -e 'CREATE DATABASE IF NOT EXISTS `homestead` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_bin;' $ sudo mysql -u root -e "CREATE USER IF NOT EXISTS devadmin@'localhost' IDENTIFIED BY 'Papy-1326';" $ sudo mysql -u root -e "CREATE USER IF NOT EXISTS devadmin@'192.168.%' IDENTIFIED BY 'Papy-1326';" $ sudo mysql -u root -e "GRANT ALL PRIVILEGES ON homestead.* TO devadmin@'localhost';" $ sudo mysql -u root -e "GRANT ALL PRIVILEGES ON homestead.* TO devadmin@'192.168.%';" $ sudo mysql -u root -e "GRANT ALL PRIVILEGES ON mysql.* TO devadmin@'192.168.%';"
プロジェクトを生成し、MySQLのパッケージをインストールする。
$ dotnet new console –o mysqlefcore $ cd mysqlefcore $ dotnet add package MySql.Data.EntityFrameworkCore --version 8.0.20 $ dotnet restore (依存関係の復元→dotnet build or run時に実行されるのでしなくてもよい)
root直下にLibraryModel.csファイルを作成。 Book, Publisherモデルを定義している。
using System.Collections.Generic;
namespace mysqlefcore
{
public class Book
{
public string ISBN { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Language { get; set; }
public int Pages { get; set; }
public virtual Publisher Publisher { get; set; }
}
public class Publisher
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
}
root直下にLibraryContext.csファイルを作成。 Entity Frameworkを使用してデータにアクセスするデータアクセス層として、DBContextの継承クラスを定義する。
using Microsoft.EntityFrameworkCore;
// using MySQL.Data.EntityFrameworkCore.Extensions;
// =>使わないし、エラーを吐くのでコメントする。
namespace mysqlefcore
{
public class LibraryContext : DbContext
{
public DbSet<Book> Book { get; set; }
public DbSet<Publisher> Publisher { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL("server=localhost;database=library;user=user;password=password");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Publisher>(entity =>
{
entity.HasKey(e => e.ID);
entity.Property(e => e.Name).IsRequired();
});
modelBuilder.Entity<Book>(entity =>
{
entity.HasKey(e => e.ISBN);
entity.Property(e => e.Title).IsRequired();
entity.HasOne(d => d.Publisher)
.WithMany(p => p.Books);
});
}
}
}
最後にProgram.csを書き換える。
using Microsoft.EntityFrameworkCore;
using System;
using System.Text;
namespace mysqlefcore
{
class Program
{
static void Main(string[] args)
{
InsertData();
PrintData();
}
private static void InsertData()
{
using(var context = new LibraryContext())
{
// Creates the database if not exists
context.Database.EnsureCreated();
// Adds a publisher
var publisher = new Publisher
{
Name = "Mariner Books"
};
context.Publisher.Add(publisher);
// Adds some books
context.Book.Add(new Book
{
ISBN = "978-0544003415",
Title = "The Lord of the Rings",
Author = "J.R.R. Tolkien",
Language = "English",
Pages = 1216,
Publisher = publisher
});
context.Book.Add(new Book
{
ISBN = "978-0547247762",
Title = "The Sealed Letter",
Author = "Emma Donoghue",
Language = "English",
Pages = 416,
Publisher = publisher
});
// Saves changes
context.SaveChanges();
}
}
private static void PrintData()
{
// Gets and prints all books in database
using (var context = new LibraryContext())
{
var books = context.Book
.Include(p => p.Publisher);
foreach(var book in books)
{
var data = new StringBuilder();
data.AppendLine($"ISBN: {book.ISBN}");
data.AppendLine($"Title: {book.Title}");
data.AppendLine($"Publisher: {book.Publisher.Name}");
Console.WriteLine(data.ToString());
}
}
}
}
}
これで $dotnet run する。
すると、最初のcontext.Database.EnsureCreated();で以下のエラーが発生する。
VagrantでUbuntu20.04LTS環境を作ってMySQL8を入れ直した方が早そう。
すると、最初のcontext.Database.EnsureCreated();で以下のエラーが発生する。
mysqlefcore Error: 0 : Authentication to host 'localhost' for user 'user' using method 'mysql_native_password' failed with message: Access denied for user 'user'@'localhost' (using password: YES)ココによると、MySQL8からデフォルトの認証方式がmysql_native_passwordから*ハッシュ化方式caching_sha2_passwordへ変更されたことによるエラーとのこと。
$ mysql --version
mysql Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
$ MariaDB [(none)]> SELECT * FROM mysql.global_priv;
| localhost | devadmin | {"access":0,"plugin":"mysql_native_password","authentication_string":"*D9547C26931028C1F3D0DEF9A477812598E3C06A","password_last_changed":1590238998}
| 192.168.% | devadmin | {"access":0,"plugin":"mysql_native_password","authentication_string":"*D9547C26931028C1F3D0DEF9A477812598E3C06A","password_last_changed":1590239017}
Vagrantのhomesteadは、MariaDB10.4でありdefaultは、mysql_native_password。
ハッシュ化方式caching_sha2_passwordはサポートされていないためNG。。VagrantでUbuntu20.04LTS環境を作ってMySQL8を入れ直した方が早そう。
参考:
コメント
コメントを投稿