5. 「NerdDinner」を動かしてみる
概要
NerdDinnerはVirtual Earth Map Controlを使用した、何らかの目的を持った会合の日時を地図情報とともに登録、およびその検索を行えるASP.NET MVCアプリケーションです。Linux上のMono環境で動かすために、次の修正を行いました。
- 「LINQ TO SQL」を「DbLinq+SQLite」に変更
- 日本語対応
Mono 2.4.2.3で提供されている「System.Data.Linq」は未実装の機能が多く、実際には使えないので、なんらかの対応をする必要があります。また、Windows上ではすべてローカル環境でまかなえますが、Linux上ではリモートのSQL Server環境が必要となり、動作確認をするには不便なので「DbLinq+SQLite」への変更を行いました。
日本語対応については、標準のままでは日本語による地図情報検索ができず、会合情報登録時に不便だったので、その対応を行いました。
ダウンロードした「NerdDinner 1.0」資源内のNerdDinnerソリューションをMonoDevelopから開き、一連の作業を行いました。
NerdDinnerプロジェクトの参照アセンブリに、「DbLinq」「DbLinq.Sqlite」「Mono.Data.Sqlite(GACから)」の追加、「System.Data.Linq(GACからではなく、Anonymous Mono SVNからチェックアウトして(2009.08.05時点)、ビルドしたものへ)」の再設定を行いました(「DbLinq」「DbLinq.Sqlite」「System.Data.Linq」各アセンブリは、本稿に添付した「NerdDinnerサンプル資源」に含まれています)。
以下、各機能の修正について解説を行います。
Models
NerdDinner DB
NerdDinnerで使用するSQLite DBのテーブル定義として、次のSQLファイルを使用しました。
-- sqlite3 NerdDinner.sqlite < NerdDinner.sql -- -- CREATE TABLE Dinners ( DinnerID integer NOT NULL, Title text NOT NULL, EventDate text NOT NULL, Description text NOT NULL, HostedBy text NOT NULL, ContactPhone text NOT NULL, Address text NOT NULL, Country text NOT NULL, Latitude real NOT NULL, Longitude real NOT NULL, CONSTRAINT PK_Dinners PRIMARY KEY (DinnerID) ); CREATE TABLE RSVP ( RsvpID integer NOT NULL, DinnerID integer NOT NULL, AttendeeName text NOT NULL, CONSTRAINT PK_RSVP PRIMARY KEY (RsvpID), CONSTRAINT FK_RSVP_Dinners FOREIGN KEY (DinnerID) REFERENCES Dinners (DinnerID) ON DELETE CASCADE ); CREATE TRIGGER FKI_RSVP_Dinners BEFORE INSERT ON RSVP FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'insert on table "RSVP" violates foreign key constraint "FK_RSVP_Dinners"') WHERE NEW.DinnerID IS NOT NULL AND (SELECT DinnerID FROM Dinners WHERE DinnerID = NEW.DinnerID) IS NULL; END; CREATE TRIGGER FKU_RSVP_Dinners BEFORE UPDATE ON RSVP FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'update on table "RSVP" violates foreign key constraint "FK_RSVP_Dinners"') WHERE NEW.DinnerID IS NOT NULL AND (SELECT DinnerID FROM Dinners WHERE DinnerID = NEW.DinnerID) IS NULL; END; CREATE TRIGGER FKD_RSVP_Dinners BEFORE DELETE ON Dinners FOR EACH ROW BEGIN SELECT RAISE(ROLLBACK, 'delete on table "Dinner" violates foreign key constraint "FK_RSVP_Dinners"') WHERE (SELECT DinnerID FROM RSVP WHERE DinnerID = OLD.DinnerID) IS NOT NULL; END;
作成した「NerdDinner.sqlite」ファイルを「プロジェクトルート/App_Data」ディレクトリへ配置します。
NerdDinner DBへの接続文字列が、「プロジェクトルート/ConnectionStrings.config」ファイルで定義されています。「NerdDinner.sqlite」向けに次の修正を行いました。
<connectionStrings> <!-- <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/> <add name="NerdDinnerConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NerdDinner.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/> --> <add name="NerdDinnerConnectionString" connectionString="Data Source=|DataDirectory|/NerdDinner.sqlite"/> </connectionStrings>
元々のNerdDinner DBでは、ユーザー定義関数(Transact-SQLによる)も定義されていますが、残念ながらSQLiteではそのような定義はできないので、別の対応をする必要があります(「Models and Helpers」で後述)。
また、元々のNerdDinner DBからサンプルデータをエクスポートし、多少加工の上、作成した「NerdDinner.sqlite」にインポートしました。