网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

在.NETMVC中对表进行通用的增删改【附示例源码】

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

预备知识:【完整示例源码下载

1、了解反射技术

2、了解C#3.0中扩展方法,分布类,Linq to object,Linq to sql

3、了解ASP.NET MVC

在项目中每添加一个表往往都要添加一套增删改代码,而且这些代码很多情况下都很相似,这里我们给出一个通用的解决方案供大家参考。

一、准备工作:

这里我们先要在数据库中添加两个表News和User如下图:然后拖到dbml中生成实体类。

这里我们先准备一个接口:ICommonTable

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

然后让News和User实体都继承于此接口

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

二、通用删除操作

分别添加NewsList.aspx和UserList.aspx两个view,添加方式参见ASP.NET MVC实践系列2-简单应用

在这两个View中加入删除链接:

<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="News" })%>


<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="User" })%>
然后添加一个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 
  6.         } 

接下来我们介绍一下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.         } 
  52.         
  53.     } 

这里边重点要理解的就是GetBllTypeByName方法。有了这个方法我们就可以动态的通过名字获得相应的Type了。这里还有个问题就是DataContext是从何而来的,我们这里为了简单起见全程声明了一个DataContext没有考虑多线程的情况

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

有个这些当我们想要对一个表进行删除是只要添加相应的链接就可以了(如<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="News" })%>)
三、通用增加、修改
首先添加一个CreateEditView.aspx视图

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

然后添加两个Partial视图News.ascx和User.ascx,这两个视图是分别基于News和User类的强类型视图,具体内容参加源码。
接下来我们添加相应的Controller

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

这里边大家可能有疑问的就是this.UpdateModel(bllTable, true);这个方法在mvc框架中并不存在,这是我添加的扩展方法,这个地方如果使用UpdateModel(bllTable)虽然编译不会报错,但也没有更新成功,查了一下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; 
  22.         } 

这个typeof(TModel)造成了只会更新声明类型中有的属性,把它换成model.GetType()就可以解决问题了,我扩这的这个方法如下

  1. public static class ControllerExtension 
  2.     { 
  3.         /// <summary> 
  4.         /// 更新时是否按照当前类型进行更新 
  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.         } 
  40.     } 

有了这些,当我们想对新表进行编辑和添加时只需要添加相应的Partial编辑视图就可以了,简化了我们的编程工作。
四、缺点
1、须要按照规则命名,比方说Partial视图需要以相应的类名来命名
2、页面引用是弱类型的

  • 下一篇资讯: 学习了解ListView控件
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师