Vici Coolstorage + Genericはすごいぞ!

C#+asp.netでアプリケーションを作ろうと思う。

で、今回フレームワークとしてVici MVCを見つけた。けっこう使いやすそう。

 

http://viciproject.com/

 

そして、DBアクセスにはvici coolstorageを使おう!

これまた、結構使いやすそう。

 

ところが、ちょっと壁にぶつかった。

というのも、データベースにはすでにデータが有る。というか初期状態のデータがすでにある。

そして、主キーはPrimaryと指定してあるが、前に作っていたプログラムでは新規レコード追加時にコードで次のキー値をセットしていた。

そして、そのキー値が別のリレーションを貼ったテーブルにも使われていた。

つまり、このフィールドは自動的にインクリメントしたいけど、いま入っている値はそのまま利用したい。

 

単純にコーディングすると、モデルクラスのイベント処理で対応できるらしい。

http://vici.stackexchange.com/questions/94/custom-primary-key-in-coolstorage

 

ところが、モデルがいっぱいあって、全部のクラスに同じコードを書くのが面倒だし、バグの元になる。

訂正が必要になったときに見落とす可能性が増えるからね。

 

いろいろ調べながらクラスを作ってみた。

やっぱりGenericはすごいね。今日もまた感動した。

 

まず、すべてのテーブルはIDという整数値のフィールドがあって、そこが主キーになっている。

なので、それをインターフェイスとして宣言する。

 

    public interface M_IDTable
    {
        int ID { get; set; }
    }

 

よし。

 

次にGenericを利用してIDフィールドの最大値+1を取ってくるメソッドを作ろう。

    public class MaxIdentifierUtil
    {
        public static int GetNext<T>() where T : CSObject<T, int>
        {
            int? MaxId = (int?)CSObject<T>.GetScalar("ID", CSAggregate.Max);
            if (MaxId == null)
            {
                return 1;
            }
            return (int)MaxId + 1;
        }

        public static void SetNextMaxID<T>(T sender, EventArgs e) where T : CSObject<T, int>, M_IDTable
        {
            sender.ID = MaxIdentifierUtil.GetNext<T>();
        }
    }

 

次に、モデルクラス。これはCSObjectを継承しなければいけない。さらに、今回作ったM_IDTableインターフェイスも実装する。

で、追加イベントで上記クラスのSetNextMaxIDメソッドを呼び出すようにする。


    [MapTo("M_UserLevel")]
    public abstract partial class M_UserLevel : CSObject<M_UserLevel, int>, M_IDTable
    {
        static M_UserLevel(){

            AnyObjectCreating += MaxIdentifierUtil.SetNextMaxID<M_UserLevel>;

        }

        public abstract int ID { get; set; }     //  Primery Key
        public abstract string Name { get;set;}
    }

 

 

動いた!!

 

ありがとうGeneric!