SQLiteでEFの一対多アソシエーション、ついでにDBNull、それと和布蕪
EntityFrameworkではデータベースからモデルを構築できるのでSQLServer等ではアソシエーションも読み込めるようです。が、SQLiteにリレーションシップを管理する機能はありません。
で、何も考えずにツールボックスからアソシエーションを選択して張ってみる。
エラー 3027: 次の EntitySet または AssociationSet にマッピングが指定されていません
怒られた。
マッピングの詳細パネルを触る。が、これは多対多のようにマッピングテーブルを用意するときに使うもので、一対多では使えない。
次の例は、Customer エンティティ型と Order エンティティ型で外部キーが公開されている場合に CustomerOrders アソシエーションを定義する Association 要素を示しています。外部キーが公開されているので、エンティティ間のリレーションシップは ReferentialConstraint 要素で管理されます。このアソシエーションをデータ ソースにマップするために、対応する AssociationSetMapping 要素は必要ありません。
http://msdn.microsoft.com/ja-jp/library/bb399734.aspx
試しにedmxを例の通りに編集してみると今度は成功。デザイナに戻って対応する箇所を探すと、アソシエーションのプロパティに「参照に関する制約」という項目が。
一側のロール名をプリンシパル、多側のロール名を依存に設定して、主キーをプリンシパルキー、外部キーを依存プロパティに設定すればいいようです。これでMSDNに書かれていた例と同じ結果になります。
ついでに整数型についてメモ
SQLiteのデータベースからモデルを生成すると、整数型の列はinteger型として扱われます。でもってこのinteger型はInt64に対応するらしい。
ここで「32bitで十分」などとモデル側の型をInt32にすると、DBNullがキャストできないと怒られます。(想像だけど、(int?)(long)valと二重にキャストされてる気がする)
これを回避するにはデータベース側の型を32bit整数型だと認識させないといけないのですが、デザイナではそれらしい項目がないのでedmxを直接編集しましょう。
StorageModels以下にテーブル情報が入っているので、ここのintegerとなっているところをintに書き換えればモデル側もInt32で処理できます。
edmxだけ書き換えても読み取りができなかった。というあたりでこんな情報が。
INTはInt32でINTEGERはINT64なことに注意。
http://www.betatechnology.jp/pp/index.php?SQLite.NET
ああSQLite側でINTにすればよかったのか・・・
それと和布蕪
http://wiki.sh4e.net/?Tips%2FOther%2FMeCab
に書かれているのですが、P/Invokeでmecab_sparse_tostrを呼び出す際はこう書かないと例外が飛んできます。
[DllImport("libmecab.dll", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.AnsiBStr)] private extern static string mecab_sparse_tostr(IntPtr m, string str);
でもこのAnsiBStrって
AnsiBStr
http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.unmanagedtype(v=VS.100).aspx
長さを示すプリフィックスを付けた 1 バイトの ANSI 文字列。このメンバーは String データ型で使用できます。
だいぶ変わり者なのにこれでいいの?ていうかVistaからこの問題が発生するってどういうことなの。
宿敵「なぜか動く」現る・・・