自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解ASP.NET MVC對(duì)表進(jìn)行通用的增刪改

開發(fā) 后端
本文將討論的是ASP.NET MVC對(duì)表進(jìn)行通用的增刪改,內(nèi)容主要適合一些輕量級(jí)的項(xiàng)目,希望本文能對(duì)大家有所幫助。

作者的寫下此文的背景是一些項(xiàng)目本身規(guī)模不大的情況下,也有其他網(wǎng)友擔(dān)心性能方面的問題。在這里我們先看一下ASP.NET MVC對(duì)表是如何進(jìn)行通用的增刪改操作的。

預(yù)備知識(shí):

1、了解反射技術(shù)

2、了解C#3.0中擴(kuò)展方法,分布類,Linq to object,Linq to sql

3、了解ASP.NET MVC

在項(xiàng)目中每添加一個(gè)表往往都要添加一套增刪改代碼,而且這些代碼很多情況下都很相似,這里我們給出一個(gè)通用的解決方案供大家參考。

一、準(zhǔn)備工作:

這里我們先要在數(shù)據(jù)庫中添加兩個(gè)表News和User如下圖:然后拖到dbml中生成實(shí)體類。

數(shù)據(jù)庫中添加兩個(gè)表News和User

這里我們先準(zhǔn)備一個(gè)接口:ICommonTable

  1. Code  
  2. public  interface ICommonTable  
  3. {  
  4. int id { getset; }  

然后讓News和User實(shí)體都繼承于此接口

  1. Code  
  2. public partial class News : ICommonTable  
  3. {  
  4. }  
  5. public partial class User : ICommonTable  
  6. {  

二、通用刪除操作

分別添加NewsList.aspx和UserList.aspx兩個(gè)view,添加方式參見ASP.NET MVC實(shí)踐系列2-簡單應(yīng)用

在這兩個(gè)View中加入刪除鏈接:

  1. <%= Html.ActionLink("刪除", "Delete", new { key = item.id, partialName="News" })%> 
  2. 和  
  3. <%= Html.ActionLink("刪除", "Delete", new { key = item.id, partialName="User" })%> 

然后添加一個(gè)Controller:

  1. public ActionResult Delete(string partialName, int? key)  
  2. {  
  3. RepositoryBase repositoryBase = new RepositoryBase(partialName);  
  4. repositoryBase.Delete(key ?? 0);  
  5. return RedirectToAction(partialName + "List");//返回到list  

接下來我們介紹一下RepositoryBase :

  1. public class RepositoryBase  
  2. {  
  3. public Type EntityType { getprivate set; }  
  4. public RepositoryBase(string entityType)  
  5. {  
  6. Type type = GetBllTypeByName(entityType);  
  7.  
  8. EntityType = type;  
  9. }  
  10. public ICommonTable CreateNew()  
  11. {  
  12. return (ICommonTable)Activator.CreateInstance(EntityType);  
  13. }  
  14. /// <summary>  
  15. /// 通過字符串獲得其Type  
  16. /// </summary>  
  17. /// <param name="typeName"></param>  
  18. /// <returns></returns>  
  19. private static Type GetBllTypeByName(string typeName)  
  20. {  
  21. Type type = null;  
  22. var ass = AppDomain.CurrentDomain.GetAssemblies()  
  23. .Where(p => p.FullName.Contains("CommonCEDemo"));  
  24. foreach (var a in ass)  
  25. {  
  26. type = a.GetTypes().Where(p => p.Name == typeName).FirstOrDefault();  
  27. if (type != null)  
  28. break;  
  29. }  
  30.  
  31. if (type == null)  
  32. {  
  33. throw new Exception("類型未定義:" + typeName);  
  34. }  
  35. return type;  
  36. }  
  37. public RepositoryBase(Type entityType)  
  38. {  
  39. EntityType = entityType;  
  40. }  
  41. public ICommonTable Get(int id)  
  42. {  
  43. DBDataContext db = Context.GetContext();  
  44. return db.GetTable(EntityType).Cast<ICommonTable>().FirstOrDefault(p => p.id == id);  
  45. }  
  46. public void Delete(int id)  
  47. {  
  48. ICommonTable bllTable = Get(id);  
  49. Context.GetContext().GetTable(EntityType).DeleteOnSubmit(bllTable);  
  50. Context.GetContext().SubmitChanges();  
  51. }  

這里邊重點(diǎn)要理解的就是GetBllTypeByName方法。有了這個(gè)方法我們就可以動(dòng)態(tài)的通過名字獲得相應(yīng)的Type了。這里還有個(gè)問題就是DataContext是從何而來的,我們這里為了簡單起見全程聲明了一個(gè)DataContext沒有考慮多線程的情況

  1. public class Context  
  2. {  
  3. static DBDataContext context;  
  4. static Context()  
  5. {  
  6. if (context==null)  
  7. {  
  8. context = new DBDataContext();  
  9. }  
  10. }  
  11. public static DBDataContext GetContext()  
  12. {  
  13. return context;  
  14. }  

有個(gè)這些當(dāng)我們想要對(duì)一個(gè)表進(jìn)行刪除是只要添加相應(yīng)的鏈接就可以了(如<%= Html.ActionLink("刪除", "Delete", new { key = item.id, partialName="News" })%>)

三、通用增加、修改

首先添加一個(gè)CreateEditView.aspx視圖

  1. <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
  2. <%Html.RenderPartial(ViewData["PartialName"].ToString()); %> 
  3. </asp:Content> 

然后添加兩個(gè)Partial視圖News.ascx和User.ascx,這兩個(gè)視圖是分別基于News和User類的強(qiáng)類型視圖,具體內(nèi)容參加源碼。
接下來我們添加相應(yīng)的Controller

  1. public ActionResult CreateEditView(string partialName, int? key)  
  2. {  
  3. ViewData["PartialName"] = partialName;  
  4. RepositoryBase repositoryBase = new RepositoryBase(partialName);  
  5. ICommonTable table;  
  6. if (key == null)  
  7. {  
  8. table = repositoryBase.CreateNew();  
  9. }  
  10. else 
  11. {  
  12. table = repositoryBase.Get(key ?? 0);  
  13. }  
  14.  
  15. return View("CreateEditView", table);  
  16. }  
  17. [AcceptVerbs(HttpVerbs.Post)]  
  18. public ActionResult CreateEditView(string partialName, int? key, FormCollection formCollection)  
  19. {  
  20. RepositoryBase repositoryBase = new RepositoryBase(partialName);  
  21. ICommonTable bllTable;  
  22. if (key == null)  
  23. {  
  24. bllTable = repositoryBase.CreateNew();  
  25. }  
  26. else 
  27. {  
  28. bllTable = repositoryBase.Get(key ?? 0);  
  29. }  
  30. this.UpdateModel(bllTable, true);  
  31. if (key == null)  
  32. {  
  33. Context.GetContext().GetTable(repositoryBase.EntityType).InsertOnSubmit(bllTable);  
  34. }  
  35. Context.GetContext().SubmitChanges();  
  36. return RedirectToAction(partialName+"List");//返回到list  

這里邊大家可能有疑問的就是this.UpdateModel(bllTable, true);這個(gè)方法在mvc框架中并不存在,這是我添加的擴(kuò)展方法,這個(gè)地方如果使用UpdateModel(bllTable)雖然編譯不會(huì)報(bào)錯(cuò),但也沒有更新成功,查了一下mvc的源碼,問題就出在如下源碼中:

  1. protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IDictionary<string, ValueProviderResult> valueProvider) where TModel : class {  
  2. if (model == null) {  
  3. throw new ArgumentNullException("model");  
  4. }  
  5. if (valueProvider == null) {  
  6. throw new ArgumentNullException("valueProvider");  
  7. }  
  8.  
  9. Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);  
  10. IModelBinder binder = Binders.GetBinder(typeof(TModel));  
  11.  
  12. ModelBindingContext bindingContext = new ModelBindingContext() {  
  13. Model = model,  
  14. ModelName = prefix,  
  15. ModelState = ModelState,  
  16. ModelType = typeof(TModel),  
  17. PropertyFilter = propertyFilter,  
  18. ValueProvider = valueProvider  
  19. };  
  20. binder.BindModel(ControllerContext, bindingContext);  
  21. return ModelState.IsValid;  

這個(gè)typeof(TModel)造成了只會(huì)更新聲明類型中有的屬性,把它換成model.GetType()就可以解決問題了,我擴(kuò)這的這個(gè)方法如下

  1. public static class ControllerExtension  
  2. {  
  3. /// <summary>  
  4. /// 更新時(shí)是否按照當(dāng)前類型進(jìn)行更新  
  5. /// </summary>  
  6. /// <typeparam name="TModel"></typeparam>  
  7. /// <param name="controller"></param>  
  8. /// <param name="model"></param>  
  9. /// <param name="isEx"></param>  
  10. public static void UpdateModel<TModel>(this Controller controller, TModel model, bool isExtension) where TModel : class 
  11. {  
  12. if (isExtension)  
  13. {  
  14. Predicate<string> propertyFilter = propertyName => IsPropertyAllowed(propertyName, nullnull);  
  15. IModelBinder binder = ModelBinders.Binders.GetBinder(model.GetType());  
  16.  
  17. ModelBindingContext bindingContext = new ModelBindingContext()  
  18. {  
  19. Model = model,  
  20. ModelName = null,  
  21. ModelState = controller.ModelState,  
  22. ModelType = model.GetType(),  
  23. PropertyFilter = propertyFilter,  
  24. ValueProvider = controller.ValueProvider  
  25. };  
  26. binder.BindModel(controller.ControllerContext, bindingContext);  
  27.  
  28. }  
  29. else 
  30. {  
  31. throw new Exception("isExtension不能選擇false");  
  32. }  
  33. }  
  34. private static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties)  
  35. {  
  36. bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);  
  37. bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);  
  38. return includeProperty && !excludeProperty;  
  39. }  

有了這些,當(dāng)我們想對(duì)新表進(jìn)行編輯和添加時(shí)只需要添加相應(yīng)的Partial編輯視圖就可以了,簡化了我們的編程工作。

四、缺點(diǎn)

1、須要按照規(guī)則命名,比方說Partial視圖需要以相應(yīng)的類名來命名

2、頁面引用是弱類型的

原文標(biāo)題:在ASP.NET MVC中對(duì)表進(jìn)行通用的增刪改

鏈接:http://www.cnblogs.com/nuaalfm/archive/2009/11/11/1600811.html

責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2009-12-01 09:30:34

ASP.NET MVC

2010-03-19 09:17:16

ASP.NET MVC

2009-09-10 09:50:47

ASP.NET MVC

2009-10-29 09:15:32

ASP.NET MVCDropDownLis

2009-09-18 10:20:26

PRG數(shù)據(jù)驗(yàn)證

2009-07-24 13:20:44

MVC框架ASP.NET

2011-04-14 09:19:22

ASP.NET MVC

2009-07-31 12:43:59

ASP.NET MVC

2010-02-03 09:50:58

ASP.NET MVC

2010-10-12 09:52:02

ASP.NET MVC

2009-07-22 10:34:37

ActionInvokASP.NET MVC

2011-04-18 09:35:59

ASP.NET MVC

2009-07-29 16:08:07

ASP和ASP.NET

2017-03-06 11:13:57

ASP.NETCoreMVC

2009-07-22 09:11:02

Action方法ASP.NET MVC

2009-07-20 15:44:32

ASP.NET MVC

2009-07-23 15:44:39

ASP.NET MVC

2009-07-22 10:09:59

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-22 13:24:24

ASP.NET MVC
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)