LoginSignup
0
0

More than 1 year has passed since last update.

.NET Core + MySQL (+ LINQ)でデータベースを扱うはじめの一歩

Last updated at Posted at 2022-11-25

はじめに

初めて.NET Core と MySQL でデータベースを扱うことになったので備忘録として残そうと思います。
今回作ったサンプル
参考にしたサイト

環境

  • MySQL 8.0.19
  • .NET Core 3.1

テスト用のテーブルをMySQLから作成

  • server: localhost
  • user: root
  • password: password
  • database: mydb

テーブル作成。
テーブル名に複数形のsをつけないと文法エラーが出るようです。


CREATE TABLE IF NOT EXISTS products (
    id INT,
    name VARCHAR(32) NOT NULL UNIQUE,
    price INT NOT NULL,
    quantity INT NOT NULL,
    PRIMARY KEY (id)
);

新規プロジェクト作成

.NET Core のコンソールアプリケーションのプロジェクトを作成します。

$ dotnet new console

MySql.Data.EntityFrameworkCore をインストール。

$ dotnet add package MySql.Data.EntityFrameworkCore
$ dotnet restore

.csproj

一応載せておきます。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.19" />
  </ItemGroup>

</Project>

中身

次のクラスを作ります。

  • テーブルのカラムと同じプロパティを持つEntityクラス
  • オブジェクトの状態とデータベースを結びつけるDbContextクラス
  • 上の2つを使って実際に操作の指示を出すメソッドを持つDataOperationクラス

それぞれ載せておきます。

Entityクラス

※今回真偽値は使っていませんが、booleanはMySQLのデータ型にないのでマップできません。bit(1)を使うとよいそうです。( 参考 )

Product.cs
    public class Product
    {
        public int id { get; set; }
        public string name { get; set; }
        public int price { get; set; }
        public int quantity { get; set; }
    }

DbContextクラス

Microsoft.EntityFrameworkCore.DbContextクラスを継承します。
DbSet<>の要素がEntityクラスで定義したものになります。
UseMySQL()内を適切に書き換えてください。直書きですみません...。

GreengrocerContext.cs
    public class GreengrocerContext : DbContext
    {
        public DbSet<Product> Products { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder.UseMySQL(@"server=localhost;database=mydb;userid=root;pwd=password;sslmode=none;");
    }

DataOperationクラス

基本的な操作のメソッドをいくつか作ってみました。
※LINQのAny()を使おうとすると、エラーが出ます。( 詳細 )
FindOrDefault()nullかどうかを調べることで同じことができます。
AsNoTracking()すると、オブジェクトの状態をデータベースに反映させません。データベースを参照するだけのときは、入れたほうが効率的だそうです。( 詳細 )

DataOperation.cs
public class DataOperation : IDisposable
    {
        private readonly GreengrocerContext context = new GreengrocerContext();
        public DataOperation(GreengrocerContext context)
        {
            this.context = context;
        }

        public void Dispose()
        {
            context.Dispose();
        }

        //データの挿入
        public void AddProduct(int id, string name, int price, int quantity)
        {
            Product newProduct = new Product
            {
                id = id,
                name = name,
                price = price,
                quantity = quantity
            };
            context.Products.Add(newProduct);
            context.SaveChanges();
        }

        //データの削除
        public void RemoveProduct(int id)
        {
            Product product = context.Products.FirstOrDefault(x => x.id == id);
            if (product != null)
            {
                context.Products.Remove(product);
                context.SaveChanges();
            }
        }

        //データの更新
        public void UpdateProductToHalfPrice(int id)
        {
            Product product = context.Products.FirstOrDefault(x => x.id == id);
            if (product != null)
            {
                product.price /= 2;
                context.SaveChanges();
            }
        }

        //全データの取得
        public List<Product> GetAllProducts()
        {
            return context.Products.ToList();
        }

        //特定のデータの取得
        public Product GetSingleProduct(string name)
        {
            return context.Products.AsNoTracking().FirstOrDefault(x => x.name == name);
        }

        //特定のデータの存在確認 ※Any()は使えません!!
        public bool AnyProducts(string name) {
            return context.Products.AsNoTracking().FirstOrDefault(x => x.name == name) != null;
        }

        //特定のデータの個数
        public int CountProductAlmostOutOfStock()
        {
            return context.Products.Count(x => x.quantity < 10);
        }
    }

これらのクラスの使用例

データを追加して、それを出力してみます。

Prigram.cs
    class Program
    {
        static void Main()
        {
            GreengrocerContext context = new GreengrocerContext();
            using DataOperation dataOpration = new DataOperation(context);
            dataOpration.AddProduct(1, "Tomato  ", 100, 30);
            dataOpration.AddProduct(2, "Cucumber", 40, 50);
            dataOpration.AddProduct(3, "Onion   ", 50, 100);
            dataOpration.AddProduct(4, "Eggplant", 80, 20);

            List<Product> products = dataOpration.GetAllProducts();
            Console.WriteLine("ID\tName    \tPrice\tQuantity");
            foreach (Product product in products)
            {
                Console.WriteLine("{0}\t{1}\t{2}\t{3}", product.id, product.name, product.price, product.quantity);
            }
        }
    }

以上です。

ご指摘、アドバイスなど歓迎いたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0