ActiveRecord.netを作ってみたよ
――まあタイトルは釣りで、「作りかけてみたよ」ってなもんですがね。.net2.0のジェネリクスとリフレクションを駆使してRuby on RailsのActiveRecord風にORマッピングするというもくろみ。
元ネタは生産性を向上させるメタオブジェクト技術 - 分裂勘違い君劇場 by ふろむだ。
class Person : ActiveRecord<Person> { public string name; public int age; }
これだけ定義してやれば、
Person hoge=Person.FindFirst("name","hoge hoge"); hoge.age=50; hoge.Save();
ってな感じにRails風味なことが可能。あとクラス定義からテーブルを生成したりもできる。
リレーション関係の機能が未実装なのでまだ役立たずだけど、Windows環境で手軽なDBアプリ作るのには向いてるんじゃないかと。
現時点でのサンプルコードはこんな感じ:
namespace Sandbox { class Person : ActiveRecord<Person> { public string name; public int age; } class Program { static DBConnector db; static void Main(string[] args) { ActiveRecordBase.EstablishConnection("test.db", "New=True"); db = Person.DB; db.DropTableIfExists("persons"); Person.CreateTable(); //Personのクラス定義からテーブルを生成する add("dilbert", 30); add("alice", 29); add("wally", 32); add("pointy-haired", 50); DispAll(); Console.WriteLine(); Console.WriteLine("add asok"); Person newbie = new Person(); newbie.name = "asok"; newbie.age = 25; newbie.Save(); DispAll(); Console.WriteLine(); Console.WriteLine("delete alice"); Person alice = Person.FindFirst("age", 29); alice.Destroy(); DispAll(); } private static void DispAll() { Console.WriteLine("==== all members ====="); foreach(Person p in Person.FindAll()) Console.WriteLine("{0} ({1})", p.name, p.age); } static void add(string name, int age) { //データ型関係がちょっとアレ db.Insert("persons", "name", "\"" + name + "\"", "age", "\"" + age.ToString() + "\""); } } } /* output: ==== all members ===== dilbert (30) alice (29) wally (32) pointy-haired (50) add asok ==== all members ===== dilbert (30) alice (29) wally (32) pointy-haired (50) asok (25) delete alice ==== all members ===== dilbert (30) wally (32) pointy-haired (50) asok (25) */
リレーション関係はこんな感じになる予定:
public class Person : ActiveRecord<Person> { public string name; public int age; public belongs_to<Company> company; } public class Company : ActiveRecord<Company> { public string name; public has_many<Person> workers; } Person.FindFirst("name","hoge").company.Get().name; Company.FindFirst("name","hoge co.,ltd.").workers.Count;
Get()のくだりがちょっとださいが、仕方なしかも。カラム名とかの設定はカスタム属性でごにゃごにゃ。