MVC3快速搭建Web應(yīng)用(一)
最近隨著項(xiàng)目接近尾聲,感覺(jué)有必要把自己”拼湊”的這一套基于asp.net mvc 3的Web應(yīng)用快速開(kāi)發(fā)模式分享出來(lái)。順便給此項(xiàng)目做個(gè)總結(jié)。
關(guān)鍵詞:Razor、easyui、Entityframework、T4 、Linq to Entity、Json
1)Razor:ASP.NET MVC3引入了一個(gè)新的View引擎.
2)easyui:基于jquery的一個(gè)ui界面框架
3)Entityframework:微軟的數(shù)據(jù)庫(kù)關(guān)系映射框架
4)T4:代碼生成的模版語(yǔ)法 。MVC中添加控制器和添加視圖對(duì)話(huà)框執(zhí)行使用在幕后的 T4 模板的代碼生成。
先來(lái)幾個(gè)效果圖:
此圖中左邊的菜單欄是通過(guò)數(shù)據(jù)庫(kù)配置動(dòng)態(tài)生成,并且與權(quán)限掛鉤,權(quán)限粒度控制到按鈕級(jí)別,即可指派某個(gè)角色是否擁有增加、刪除某記錄的權(quán)限
圖中列表的header全部都是通過(guò)自動(dòng)生成完成,設(shè)備詳細(xì)信息頁(yè)面經(jīng)由改造mvc3的details生成。
此編輯界面也是由T4模版自動(dòng)生成。甚至包括中文label(提取自Powerdesigner中的字段注釋?zhuān)?,包括下拉列表,日期選擇框,都是根據(jù)判斷數(shù)據(jù)庫(kù)類(lèi)型自動(dòng)添加。
#p#
一、使用PowerDesigner搭建數(shù)據(jù)模型
在EntityFramework中,有兩種開(kāi)發(fā)模式,代碼優(yōu)先(Code First)與普通的先生成數(shù)據(jù)庫(kù)然后再開(kāi)發(fā),本項(xiàng)目采用的是后一種。
個(gè)人習(xí)慣直接搭建概念模型,需求初步敲定后,為物理模型添加細(xì)節(jié),在這個(gè)期間,給每個(gè)字段添加注釋是非常重要的,因?yàn)楹笃谀阈枰鶕?jù)這些中文注釋來(lái)生成界面上的文字。本人使用了一個(gè)Powerdesigner中的自動(dòng)修改腳本來(lái)將Name轉(zhuǎn)換為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
上圖為本項(xiàng)目物理模型的縮略圖。
在業(yè)務(wù)比較復(fù)雜的情況下,設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí),其中數(shù)據(jù)字段冗余與處理邏輯簡(jiǎn)化之間的權(quán)衡最為關(guān)鍵。最常見(jiàn)是業(yè)務(wù)域中對(duì)象的繼承與組合關(guān)系。例如,某些種類(lèi)的設(shè)備擁有特殊信息,而大部分設(shè)備的字段都是通用的,這個(gè)時(shí)候就該權(quán)衡是放在多個(gè)表還是一個(gè)表?yè)碛卸鄠€(gè)冗余字段,在本案例中,采用一個(gè)父表“設(shè)備”(包含有所有設(shè)備通用的字段),多個(gè)種類(lèi)子表(存儲(chǔ)特殊字段)的設(shè)計(jì),減少字段冗余,提高系統(tǒng)擴(kuò)充性。當(dāng)然這是針對(duì)這個(gè)項(xiàng)目的特殊性來(lái)設(shè)計(jì)的,設(shè)備的種類(lèi)變化不會(huì)很大。
另外設(shè)置一些公共表也是非常有必要的,在本案例中,有一個(gè)公共照片表,包含字段有
這樣的話(huà)可以給任何信息表添加照片,信息表中包含的數(shù)據(jù)表記錄編號(hào)存的是某個(gè)表的主鍵id,表編號(hào)存的是對(duì)應(yīng)的信息表。
數(shù)據(jù)庫(kù)設(shè)計(jì)完畢,利用PowerDesigner直接生成到數(shù)據(jù)庫(kù)。本項(xiàng)目采用的是SQL Server 2008,因?yàn)镋ntityFramework目前只支持微軟自家的東西。
在生成數(shù)據(jù)庫(kù)的過(guò)程中,如果你的SQL Server是2005以上,你必須解決:
PowerDesigner 16 Generate Datebase For Sql2005 找不到sysproperties表的問(wèn)題
#p#
二、給項(xiàng)目添加Entity Framework 支持
假定你的vs2010已經(jīng)安裝mvc3。
解決方案中只有兩個(gè)項(xiàng)目:Domain與WebUI,顧名思義,Domain中涉及的是域模型相關(guān)數(shù)據(jù)訪(fǎng)問(wèn),在本項(xiàng)目中也就是Entityframework生成的實(shí)體數(shù)據(jù)模型,WebUI里存放控制器與視圖.
圖中的edmx文件就是我們的實(shí)體數(shù)據(jù)模型。你可以在新建該文件后通過(guò)右鍵,添加或刷新數(shù)據(jù)庫(kù),以便更新當(dāng)前的實(shí)體模型與數(shù)據(jù)庫(kù)匹配。
當(dāng)你按下保存鍵時(shí),微軟牛逼的T4模版在后臺(tái)悄悄地給你生成了一大堆實(shí)體類(lèi)。你可以展開(kāi)edmx文件查看到它們:
大概是一個(gè)這樣的結(jié)構(gòu):上下文與實(shí)體,其中上下文繼承自O(shè)bjectContext,姑且可以把它當(dāng)作三層架構(gòu)中的數(shù)據(jù)訪(fǎng)問(wèn)層,實(shí)體類(lèi) 即三層架構(gòu)中的實(shí)體層。
如果你想深入這個(gè)自動(dòng)生成過(guò)程,例如想修改生成后的實(shí)體名字,你可以修改edmx的屬性--自定義工具。但我覺(jué)得太蛋疼了,所以保持默認(rèn)的生成方式:EntityModelCodeGenerator,結(jié)果我的所有實(shí)體類(lèi)名稱(chēng)全部都是T_前綴(我數(shù)據(jù)庫(kù)中的表全都以T_開(kāi)頭)。
至此,你的數(shù)據(jù)工作準(zhǔn)備完畢,注意,你不需要寫(xiě)一句SQL。并且,將來(lái)你對(duì)數(shù)據(jù)庫(kù)的任何更改將隨著你在edmx文件上瀟灑的右擊刷新自動(dòng)同步到你的項(xiàng)目中,一切是辣么的舒服,自然
#p#
三、修改T4模版
這是最為關(guān)鍵的一步,貌似也是整個(gè)項(xiàng)目中相對(duì)于其他步驟來(lái)說(shuō)稍微有技術(shù)含量的一步。因?yàn)槟愕昧私釺4模版語(yǔ)法,你得事先編寫(xiě)一個(gè)完整的增刪改頁(yè)面(頁(yè)面內(nèi)容包含Razor語(yǔ)法,easyui,ajax等技術(shù))。
但是當(dāng)這一步完成后,你的項(xiàng)目就完成70%的工作了。對(duì),沒(méi)錯(cuò)!完成一大半了!
首先來(lái)感覺(jué)一下T4語(yǔ)法,如果你VS是默認(rèn)路徑,辣么你可以在這個(gè)路徑下找到我們語(yǔ)法非??拥哪0妫ㄒ?yàn)橹两駴](méi)有太智能的編輯器能編輯它們,只能憑感覺(jué)手寫(xiě)了)
C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 3\CodeTemplates
其中AddController就是你在VS中右鍵添加控制器時(shí)執(zhí)行的模版,AddView是添加視圖時(shí)執(zhí)行的模版。為什么要修改他們?因?yàn)槲覀兿胍尤雑query,加入easyui,加入Json,想要有更好的頁(yè)面體驗(yàn)與異步處理。
AddController文件夾下有兩個(gè):我們需要修改的是ControllerWithContext.tt,下面會(huì)提供下載.內(nèi)容就不細(xì)述了。舉兩個(gè)例子就OK了,詳細(xì)大家下載后再討論:(cnblogs的編輯器沒(méi)有T4的語(yǔ)法著色。只能勉強(qiáng)看了)
- 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);
- }
上面這個(gè)方法是給控制器增加了一個(gè)返回jsonresult的列表方法。眾所周知,數(shù)據(jù)庫(kù)表操作無(wú)非就是增刪改查,這個(gè)List就是用來(lái)支持列表的。參數(shù)page與rows是用來(lái)支持easyui的grid分頁(yè)的。
- [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,失敗返回失敗原因。
本項(xiàng)目中非常多的控制器httpPost方法是返回jsonresult 。目的有兩個(gè):
一:為了支持easyui;二:本項(xiàng)目還有一個(gè)客戶(hù)端是android平板,控制器當(dāng)作它的一個(gè)遠(yuǎn)程數(shù)據(jù)源,給平板上的應(yīng)用提供json格式數(shù)據(jù)。
關(guān)于T4模版,你可以參考這里。
好,先寫(xiě)到這。馬上回來(lái)。
我的自定義模版下載。未完待續(xù)......
原文鏈接:http://www.cnblogs.com/limlee/archive/2012/06/21/2557832.html