jqGridとEntity Frameworkの連携
手順
2.jqGridからジェネリックハンドラに飛ばすように書き換えます。
datatypeプロパティを'local'からサーバー側の処理を得て受け取ったJSONデータを扱えるようにfunctionに変更します。
$("#momoclo").jqGrid({ editurl: "/Service/MomocloHandler.ashx", datatype: function (postData) { //ajaxメソッドによるPOST通信の結果をjqGridに設定する $.ajax({ type: "POST", url: "/Service/MomocloHandler.ashx", success: function (responseData) { //JSON形式の文字列をJavascriptオブジェクトに変換する var json_res = $.parseJSON(responseData); console.log("response:" + responseData); $("#momoclo")[0].addJSONData(json_res); } }); }, jsonReader: { page: "page", total: "total", records: "records", root: "data", repeatitems: false, id: "id" }, width: 600, height: '100%', rownumbers: true, shrinkToFit: false, hidegrid: false, pager: "#pager", pgbuttons: false, pginput: false, viewrecords: true, colNames: ['id', '色', '名前', '誕生日', '血液型', '出身地', '身長'], colModel: [ { 'name': 'id', 'index': 'id', 'width': 30, 'editable': true, 'hidden': true },//id列は非表示 { 'name': 'color', 'width': 80, 'editable': true }, { 'name': 'name', 'width': 130, 'editable': true }, { 'name': 'birth', 'width': 90, 'editable': true, 'datefmt': "yyyy/mm/dd", 'editrules': { date: true }, 'title': false }, { 'name': 'bloodtype', 'width': 50, 'editable': true, 'edittype': "select", 'editoptions': { value: ":;0:A;1:B;2:AB;3:O" }, 'title': false }, { 'name': 'birthplace', 'width': 80, 'editable': true }, { 'name': 'height', 'width': 50, 'editable': true } ], caption: 'ももクロ', serializeRowData: function (data) { $.each(data, function (k, v) { console.log(k + ":" + v); }); //編集データを渡します return data; } }); $('#momoclo').jqGrid('navGrid', '#pager', { edit: false, add: false, del: true, search: false }); $('#momoclo').jqGrid('inlineNav', '#pager', { edit: true, editicon: "ui-icon-pencil", add: true, addicon: "ui-icon-plus", save: true, saveicon: "ui-icon-disk", cancel: true, cancelicon: "ui-icon-cancel", editParams: { oneditfunc: onEdit }, addParams: { "rowID": 0, //id列の初期値←これを設定しないとid列が"jqg1"となってしまう "addRowParams": { oneditfunc: onEdit, successfunc: function (response) { //データ追加後リロードしないとid列が0のままとなってしまう $('#momoclo').trigger("reloadGrid"); return true; } } } }); function onEdit(id) { $("#" + id + "_birth").datepicker({ changeMonth: true, changeYear: true, dateFormat: 'yy/mm/dd', yearRange: '1970:2100' }).addClass("grid-datepicker"); }
3.ジェネリックハンドラを用意します。
MomocloHandler.ashx.csを作成します。
POSTで受け取った[oper]の内容で処理を振り分けます。
using System.Transactions; using System.Web; using Momoclo.DAO; using Momoclo.Util; using Momoclo.View; namespace Momoclo.Service { public class MomocloRequest { public int id { get; set; } public string color { get; set; } public string name { get; set; } public string birth { get; set; } public string bloodtype { get; set; } public string birthplace { get; set; } public string height { get; set; } public string oper { get; set; } } /// <summary> /// MomocloHandler の概要の説明 /// </summary> public class MomocloHandler : IHttpHandler { private const string ADD = "add"; private const string EDIT = "edit"; private const string DEL = "del"; HttpContext context; MomocloRequest req = new MomocloRequest(); public void ProcessRequest(HttpContext context) { this.context = context; if (context.Request.HttpMethod == "GET") { System.Diagnostics.Debug.WriteLine("GET"); } else if (context.Request.HttpMethod == "POST") { System.Diagnostics.Debug.WriteLine("POST"); string id = context.Request.Form["id"]; req.id = int.Parse(Utility.NullToZero(id)); req.color = context.Request.Form["color"]; req.name = context.Request.Form["name"]; req.birth = context.Request.Form["birth"]; req.bloodtype = context.Request.Form["bloodtype"]; req.birthplace = context.Request.Form["birthplace"]; req.height = context.Request.Form["height"]; req.oper = context.Request.Form["oper"]; } switch (req.oper) { case ADD: Save(); break; case EDIT: Save(); break; case DEL: Remove(); break; default: Load(); break; } } private void Load() { context.Response.ContentType = "text/plain"; var s = new System.Web.Script.Serialization.JavaScriptSerializer(); MomocloDAO dao = new MomocloDAO(); MemberView[] members = dao.Select(); context.Response.Write(s.Serialize(members)); context.Response.End(); } private void Save() { using (TransactionScope transaction = new TransactionScope()) { MomocloDAO dao = new MomocloDAO(); dao.Save(req); transaction.Complete(); } } private void Remove() { using (TransactionScope transaction = new TransactionScope()) { MomocloDAO dao = new MomocloDAO(); dao.Remove(req); transaction.Complete(); } } } }
4.データ処理クラスを用意します。
オブジェクトコンテキスト生成
namespace Momoclo.Common { public class DBUtil { private MomocloEDMContainer container; public MomocloEDMContainer MContainer { get { if (container == null) { container = new MomocloEDMContainer(); } return container; } } } }
#後日追記
現在開発中プロジェクトのフレームワークに従ってこのような書き方をしてしまいましたが、このオブジェクトコンテキストの使い方は問題が起きました。
なんちゃってシングルトンのため、ひとつのオブジェクトコンテキストのインスタンスを使い続けることによって、トランザクションに影響を及ぼしてしまいます。
オブジェクトコンテキストを使う場合はusingステートメントで囲んで、都度インスタンスを生成し、使うよう修正しています。
CRUD処理を書きます。
using System.Collections.Generic; using System.Linq; using Momoclo.Common; using Momoclo.Service; using Momoclo.Util; using Momoclo.View; namespace Momoclo.DAO { public class MomocloDAO : DBUtil { public MemberView[] Select() { var rs = from mem in this.MContainer.Members select mem; //jqGridの項目名に合わせてマッピング List<MemberView> members = new List<MemberView>(); foreach (Member member in rs) { MemberView view = new MemberView(); view.id = member.ID; view.color = member.Color; view.name = member.Name; view.birth = member.Birth; view.bloodtype = getBloodtype(member.Bloodtype); view.birthplace = member.Birthplace; view.height = member.Height.ToString(); members.Add(view); } return members.ToArray(); } public void Save(MomocloRequest req) { if (req.id > 0) { //更新 var rs = from mem in this.MContainer.Members where mem.ID == req.id select mem; Member oldRec = rs.Single(); oldRec.Color = req.color; oldRec.Name = req.name; oldRec.Birth = req.birth; oldRec.Bloodtype = req.bloodtype; oldRec.Birthplace = req.birthplace; oldRec.Height = Utility.NullorValue(req.height); } else { //新規登録 Member member = new Member(); member.Color = req.color; member.Name = req.name; member.Birth = req.birth; member.Bloodtype = req.bloodtype; member.Birthplace = req.birthplace; member.Height = Utility.NullorValue(req.height); this.MContainer.Members.AddObject(member); } this.MContainer.SaveChanges(); } public void Remove(MomocloRequest req) { var rs = from mem in this.MContainer.Members where mem.ID == req.id select mem; this.MContainer.Members.DeleteObject(rs.Single()); this.MContainer.SaveChanges(); } private string getBloodtype(string s) { switch(s){ case "0": return "A"; case "1": return "B"; case "2": return "AB"; case "3": return "O"; default : return null; } } } }
5.データベース定義とjqGridの定義をマッピングするクラスを用意します。
jqGridでは項目の定義を小文字、SQLServerでは項目の定義を頭文字大文字で定義しているため、jqGridの項目名にマッピングして返します。
namespace Momoclo.View { public class MemberView { public int id { get; set; } public string color { get; set; } public string name { get; set; } public string birth { get; set; } public string bloodtype { get; set; } public string birthplace { get; set; } public string height { get; set; } } }
完成