MVC3快速搭建Web應用(一)
最近隨著項目接近尾聲,感覺有必要把自己”拼湊”的這一套基于asp.net mvc 3的Web應用快速開發模式分享出來。順便給此項目做個總結。
關鍵詞:Razor、easyui、Entityframework、T4 、Linq to Entity、Json
1)Razor:ASP.NET MVC3引入了一個新的View引擎.
2)easyui:基于jquery的一個ui界面框架
3)Entityframework:微軟的數據庫關系映射框架
4)T4:代碼生成的模版語法 。MVC中添加控制器和添加視圖對話框執行使用在幕后的 T4 模板的代碼生成。
先來幾個效果圖:
此圖中左邊的菜單欄是通過數據庫配置動態生成,并且與權限掛鉤,權限粒度控制到按鈕級別,即可指派某個角色是否擁有增加、刪除某記錄的權限
圖中列表的header全部都是通過自動生成完成,設備詳細信息頁面經由改造mvc3的details生成。
此編輯界面也是由T4模版自動生成。甚至包括中文label(提取自Powerdesigner中的字段注釋),包括下拉列表,日期選擇框,都是根據判斷數據庫類型自動添加。
#p#
一、使用PowerDesigner搭建數據模型
在EntityFramework中,有兩種開發模式,代碼優先(Code First)與普通的先生成數據庫然后再開發,本項目采用的是后一種。
個人習慣直接搭建概念模型,需求初步敲定后,為物理模型添加細節,在這個期間,給每個字段添加注釋是非常重要的,因為后期你需要根據這些中文注釋來生成界面上的文字。本人使用了一個Powerdesigner中的自動修改腳本來將Name轉換為Commet
- Option Explicit
- ValidationMode = True
- InteractiveMode = im_Batch
- Dim mdl 'the current model
- 'get the current active model
- Set mdl = ActiveModel
- If (mdl Is Nothing) Then
- MsgBox "There is no current Model"
- ElseIf Not mdl.IsKindOf(PdPDM.cls_Model) Then
- MsgBox "The current model is not an Physical Data model."
- Else
- ProcessFolder mdl
- End If
- 'This routine copy name into code for each table, each column and each view
- 'of the current folder
- Private sub ProcessFolder(folder)
- Dim Tab 'running table
- for each Tab in folder.tables
- if not Tab.isShortcut then
- if Tab.Comment ="" then
- Tab.Comment = tab.name
- else
- Tab.comment=Tab.name &"," &Tab.comment
- End if
- Dim col 'running column
- for each col in tab.columns
- if col.comment ="" then
- col.comment= col.name
- else
- col.comment=col.name & "," &col.comment
- end if
- next
- end if
- next
- Dim view 'running view
- for each view in folder.Views
- if not view.isShortcut then
- view.comment = view.name
- end if
- next
- 'go into the sub-packages
- Dim f 'running folder
- For Each f In folder.Packages
- if not f.IsShortcut then
- ProcessFolder f
- end if
- Next
- end sub
上圖為本項目物理模型的縮略圖。
在業務比較復雜的情況下,設計數據庫時,其中數據字段冗余與處理邏輯簡化之間的權衡最為關鍵。最常見是業務域中對象的繼承與組合關系。例如,某些種類的設備擁有特殊信息,而大部分設備的字段都是通用的,這個時候就該權衡是放在多個表還是一個表擁有多個冗余字段,在本案例中,采用一個父表“設備”(包含有所有設備通用的字段),多個種類子表(存儲特殊字段)的設計,減少字段冗余,提高系統擴充性。當然這是針對這個項目的特殊性來設計的,設備的種類變化不會很大。
另外設置一些公共表也是非常有必要的,在本案例中,有一個公共照片表,包含字段有
這樣的話可以給任何信息表添加照片,信息表中包含的數據表記錄編號存的是某個表的主鍵id,表編號存的是對應的信息表。
數據庫設計完畢,利用PowerDesigner直接生成到數據庫。本項目采用的是SQL Server 2008,因為EntityFramework目前只支持微軟自家的東西。
在生成數據庫的過程中,如果你的SQL Server是2005以上,你必須解決:
PowerDesigner 16 Generate Datebase For Sql2005 找不到sysproperties表的問題
#p#
二、給項目添加Entity Framework 支持
假定你的vs2010已經安裝mvc3。
解決方案中只有兩個項目:Domain與WebUI,顧名思義,Domain中涉及的是域模型相關數據訪問,在本項目中也就是Entityframework生成的實體數據模型,WebUI里存放控制器與視圖.
圖中的edmx文件就是我們的實體數據模型。你可以在新建該文件后通過右鍵,添加或刷新數據庫,以便更新當前的實體模型與數據庫匹配。
當你按下保存鍵時,微軟牛逼的T4模版在后臺悄悄地給你生成了一大堆實體類。你可以展開edmx文件查看到它們:
大概是一個這樣的結構:上下文與實體,其中上下文繼承自ObjectContext,姑且可以把它當作三層架構中的數據訪問層,實體類 即三層架構中的實體層。
如果你想深入這個自動生成過程,例如想修改生成后的實體名字,你可以修改edmx的屬性--自定義工具。但我覺得太蛋疼了,所以保持默認的生成方式:EntityModelCodeGenerator,結果我的所有實體類名稱全部都是T_前綴(我數據庫中的表全都以T_開頭)。
至此,你的數據工作準備完畢,注意,你不需要寫一句SQL。并且,將來你對數據庫的任何更改將隨著你在edmx文件上瀟灑的右擊刷新自動同步到你的項目中,一切是辣么的舒服,自然
#p#
三、修改T4模版
這是最為關鍵的一步,貌似也是整個項目中相對于其他步驟來說稍微有技術含量的一步。因為你得了解T4模版語法,你得事先編寫一個完整的增刪改頁面(頁面內容包含Razor語法,easyui,ajax等技術)。
但是當這一步完成后,你的項目就完成70%的工作了。對,沒錯!完成一大半了!
首先來感覺一下T4語法,如果你VS是默認路徑,辣么你可以在這個路徑下找到我們語法非常坑爹的模版(因為至今沒有太智能的編輯器能編輯它們,只能憑感覺手寫了)
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 3\CodeTemplates
其中AddController就是你在VS中右鍵添加控制器時執行的模版,AddView是添加視圖時執行的模版。為什么要修改他們?因為我們想要加入jquery,加入easyui,加入Json,想要有更好的頁面體驗與異步處理。
AddController文件夾下有兩個:我們需要修改的是ControllerWithContext.tt,下面會提供下載.內容就不細述了。舉兩個例子就OK了,詳細大家下載后再討論:(cnblogs的編輯器沒有T4的語法著色。只能勉強看了)
- public JsonResult List(int page,int rows)
- {
- var q = from e in db.<#= entitySetName #> orderby e.<#=primaryKey.Name#>
- select new
- {
- <#int i=0;
- foreach (ModelProperty property in GetModelProperties(Model.ModelType)) {#>
- <#=property.Name #> = e.<#=property.Name #><#if(i!=GetModelProperties(Model.ModelType).Count-1){#>,
- <#}#>
- <# i++; }#>
- };
- var result = q.Skip((page - 1)*rows).Take(rows).ToList();
- Dictionary<string, object> json = new Dictionary<string, object>();
- json.Add("total", q.ToList().Count);
- json.Add("rows", result);
- return Json(json, JsonRequestBehavior.AllowGet);
- }
上面這個方法是給控制器增加了一個返回jsonresult的列表方法。眾所周知,數據庫表操作無非就是增刪改查,這個List就是用來支持列表的。參數page與rows是用來支持easyui的grid分頁的。
- [HttpPost]
- public JsonResult Create(<#= modelName #> <#= modelVariable #>)
- {
- JsonResult json=new JsonResult();
- json.Data=true;
- try{
- <# if(isObjectContext) { #>
- db.<#= entitySetName #>.AddObject(<#= modelVariable #>);
- <# } else { #>
- db.<#= entitySetName #>.Add(<#= modelVariable #>);
- <# } #>
- db.SaveChanges();
- }
- catch(Exception ee)
- {
- json.Data=ee.Message;
- }
- return json;
- }
Create是為了支持新建。成功返回json格式的true,失敗返回失敗原因。
本項目中非常多的控制器httpPost方法是返回jsonresult 。目的有兩個:
一:為了支持easyui;二:本項目還有一個客戶端是android平板,控制器當作它的一個遠程數據源,給平板上的應用提供json格式數據。
關于T4模版,你可以參考這里。
好,先寫到這。馬上回來。
我的自定義模版下載。未完待續......
原文鏈接:http://www.cnblogs.com/limlee/archive/2012/06/21/2557832.html