前回、PetaPoco の Insert/Update/Delete メソッドを使ってみたが、いちいちテーブル名とプライマリーキーを指定していた。

PetaPoco の Insert/Update/Delete メソッドではこれらを省略することができる。そのためには POCO のクラス定義に、テーブル名の属性 TableName とプライマリーキー PrimaryKey を属性として指定しておく。なお、今回の例のようにテーブル名がクラス名と一致している場合は、TableName 属性を指定する必要はなさそうだ。

Product テーブルのキーである ProductId は自動インクリメントID なので、PrimaryKey 属性に「autoincrement = true」を指定している。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using PetaPoco;
 
namespace PetaPocoTest1
{
    public partial class Form1 : Form
    {
        private string connectionString = "Data Source=(local);Database=ORMTest;User ID=ORMTest_user;Password=ORMTest_password";
 
        public Form1()
        {
            InitializeComponent();
 
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.Columns.AddRange(
                new DataGridViewTextBoxColumn()
                {
                    DataPropertyName = "ProductId",
                    Name = "ProductId",
                },
                new DataGridViewTextBoxColumn()
                {
                    DataPropertyName = "Name",
                    Name = "Name",
                },
                new DataGridViewTextBoxColumn()
                {
                    DataPropertyName = "Price",
                    Name = "Price",
                },
                new DataGridViewTextBoxColumn()
                {
                    DataPropertyName = "SubCategoryId",
                    Name = "SubCategoryId",
                },
                new DataGridViewTextBoxColumn()
                {
                    DataPropertyName = "SubCategoryName",
                    Name = "SubCategoryName",
                },
                new DataGridViewTextBoxColumn()
                {
                    DataPropertyName = "CategoryName",
                    Name = "CategoryName",
                }
            );
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            var db = new PetaPoco.Database(connectionString, "System.Data.SqlClient");
            var resultList = db.Query<Product, SubCategory, Category, Product>(
                    (p, s, c) => { p.SubCategory = s; s.Category = c; return p; },
                    @"SELECT p.*, s.*, c.* FROM Product p 
                    INNER JOIN SubCategory s ON s.SubCategoryId = p.SubCategoryId
                    INNER JOIN Category c ON c.CategoryId = s.CategoryId"
                );
            dataGridView1.DataSource = resultList.ToList();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            var db = new PetaPoco.Database(connectionString, "System.Data.SqlClient");
            var newProduct = new Product() { Name = "弱虫ペダル(30)", Price = 450, SubCategoryId = 100, };
            var newProductId = db.Insert(newProduct);
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            var db = new PetaPoco.Database(connectionString, "System.Data.SqlClient");
            var resultList = db.Query<Product>(
                    @"SELECT p.* FROM Product p WHERE ProductId >= @ProductId",
                    new { ProductId = 6 }
                );
            resultList.ToList().ForEach(product => {
                product.Name = "ポケットモンスター X";
                product.Price = 3918;
                product.SubCategoryId = 200;
                var newProductId = db.Update(product);
            });
        }
 
        private void button4_Click(object sender, EventArgs e)
        {
            var db = new PetaPoco.Database(connectionString, "System.Data.SqlClient");
            var resultList = db.Query<Product>(
                    @"SELECT p.* FROM Product p WHERE ProductId >= @ProductId",
                    new { ProductId = 6 }
                );
            resultList.ToList().ForEach(product =>
            {
                var newProductId = db.Delete(product);
            });
        }
    }
 
    [TableName("Product")]
    [PrimaryKey("ProductId", autoIncrement = true)]
    public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
        public int SubCategoryId { get; set; }
 
        [ResultColumn]
        public SubCategory SubCategory { get; set; }
        [ResultColumn]
        public string SubCategoryName { get { return SubCategory.Name; } }
        [ResultColumn]
        public string CategoryName { get { return SubCategory.Category.Name; } }
    }
 
    [TableName("SubCategory")]
    [PrimaryKey("SubCategoryId", autoIncrement = false)]
    public class SubCategory
    {
        public int SubCategoryId { get; set; }
        public string Name { get; set; }
        public int CategoryId { get; set; }
 
        [ResultColumn]
        public Category Category { get; set; }
    }
 
    [TableName("Category")]
    [PrimaryKey("CategoryId", autoIncrement = false)]
    public class Category
    {
        public int CategoryId { get; set; }
        public string Name { get; set; }
    }
}

Insert/Update/Delete メソッドが少しすっきり書けるだけであるが、POCO の定義は一度だけで、何度もInsert/Update/Delete メソッドの呼び出しを行うことを考えれば、ずいぶん助かると思う。

以上