|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
简单的说:.net只有微软一家在做的,微软也不允许别人跟他做相同的工具,所以他就把需要的工具全部封装在.net的平台上了;而java是公开了。作者的写下此文的背景是一些项目自己范围不年夜的情形下,也有其他网友忧虑功能方面的成绩。在这里我们先看一下ASP.NETMVC对表是怎样举行通用的增编削操纵的。
准备常识:
1、懂得反射手艺
2、懂得C#3.0中扩大办法,散布类,Linqtoobject,Linqtosql
3、懂得ASP.NETMVC
在项目中每增加一个表常常都要增加一套增编削代码,并且这些代码良多情形下都很类似,这里我们给出一个通用的办理计划供人人参考。
1、筹办事情:
这里我们先要在数据库中增加两个表News和User以下图:然后拖到dbml中天生实体类。
这里我们先筹办一个接口:ICommonTable
Code
publicinterfaceICommonTable
{
intid{get;set;}
}
然后让News和User实体都承继于此接口
Code
publicpartialclassNews:ICommonTable
{
}
publicpartialclassUser:ICommonTable
{
}
2、通用删除操纵
分离增加NewsList.aspx和UserList.aspx两个view,增加体例拜见ASP.NETMVC理论系列2-复杂使用
在这两个View中到场删除链接:
<%=Html.ActionLink("删除","Delete",new{key=item.id,partialName="News"})%>
和
<%=Html.ActionLink("删除","Delete",new{key=item.id,partialName="User"})%>
然后增加一个Controller:
publicActionResultDelete(stringpartialName,int?key)
{
RepositoryBaserepositoryBase=newRepositoryBase(partialName);
repositoryBase.Delete(key??0);
returnRedirectToAction(partialName+"List");//前往到list
}
接上去我们先容一下RepositoryBase:
publicclassRepositoryBase
{
publicTypeEntityType{get;privateset;}
publicRepositoryBase(stringentityType)
{
Typetype=GetBllTypeByName(entityType);
EntityType=type;
}
publicICommonTableCreateNew()
{
return(ICommonTable)Activator.CreateInstance(EntityType);
}
///<summary>
///经由过程字符串取得其Type
///</summary>
///<paramname="typeName"></param>
///<returns></returns>
privatestaticTypeGetBllTypeByName(stringtypeName)
{
Typetype=null;
varass=AppDomain.CurrentDomain.GetAssemblies()
.Where(p=>p.FullName.Contains("CommonCEDemo"));
foreach(varainass)
{
type=a.GetTypes().Where(p=>p.Name==typeName).FirstOrDefault();
if(type!=null)
break;
}
if(type==null)
{
thrownewException("范例不决义:"+typeName);
}
returntype;
}
publicRepositoryBase(TypeentityType)
{
EntityType=entityType;
}
publicICommonTableGet(intid)
{
DBDataContextdb=Context.GetContext();
returndb.GetTable(EntityType).Cast<ICommonTable>().FirstOrDefault(p=>p.id==id);
}
publicvoidDelete(intid)
{
ICommonTablebllTable=Get(id);
Context.GetContext().GetTable(EntityType).DeleteOnSubmit(bllTable);
Context.GetContext().SubmitChanges();
}
}
这里边重点要了解的就是GetBllTypeByName办法。有了这个办法我们就能够静态的经由过程名字取得响应的Type了。这里另有个成绩就是DataContext是从何而来的,我们这里为了复杂起见全程声了然一个DataContext没有思索多线程的情形
publicclassContext
{
staticDBDataContextcontext;
staticContext()
{
if(context==null)
{
context=newDBDataContext();
}
}
publicstaticDBDataContextGetContext()
{
returncontext;
}
}
有个这些当我们想要对一个表举行删除是只需增加响应的链接就能够了(如<%=Html.ActionLink("删除","Delete",new{key=item.id,partialName="News"})%>)
3、通用增添、修正
起首增加一个CreateEditView.aspx视图
<asp:ContentID="Content2"ContentPlaceHolderID="MainContent"runat="server">
<%Html.RenderPartial(ViewData["PartialName"].ToString());%>
</asp:Content>
然后增加两个Partial视图News.ascx和User.ascx,这两个视图是分离基于News和User类的强范例视图,详细内容列入源码。
接上去我们增加响应的Controller
publicActionResultCreateEditView(stringpartialName,int?key)
{
ViewData["PartialName"]=partialName;
RepositoryBaserepositoryBase=newRepositoryBase(partialName);
ICommonTabletable;
if(key==null)
{
table=repositoryBase.CreateNew();
}
else
{
table=repositoryBase.Get(key??0);
}
returnView("CreateEditView",table);
}
[AcceptVerbs(HttpVerbs.Post)]
publicActionResultCreateEditView(stringpartialName,int?key,FormCollectionformCollection)
{
RepositoryBaserepositoryBase=newRepositoryBase(partialName);
ICommonTablebllTable;
if(key==null)
{
bllTable=repositoryBase.CreateNew();
}
else
{
bllTable=repositoryBase.Get(key??0);
}
this.UpdateModel(bllTable,true);
if(key==null)
{
Context.GetContext().GetTable(repositoryBase.EntityType).InsertOnSubmit(bllTable);
}
Context.GetContext().SubmitChanges();
returnRedirectToAction(partialName+"List");//前往到list
}
这里边人人大概有疑问的就是this.UpdateModel(bllTable,true);这个办法在mvc框架中其实不存在,这是我增加的扩大办法,这个中央假如利用UpdateModel(bllTable)固然编译不会报错,但也没有更新乐成,查了一下mvc的源码,成绩就出在以下源码中:
protectedinternalboolTryUpdateModel<TModel>(TModelmodel,stringprefix,string[]includeProperties,string[]excludeProperties,IDictionary<string,ValueProviderResult>valueProvider)whereTModel:class{
if(model==null){
thrownewArgumentNullException("model");
}
if(valueProvider==null){
thrownewArgumentNullException("valueProvider");
}
Predicate<string>propertyFilter=propertyName=>BindAttribute.IsPropertyAllowed(propertyName,includeProperties,excludeProperties);
IModelBinderbinder=Binders.GetBinder(typeof(TModel));
ModelBindingContextbindingContext=newModelBindingContext(){
Model=model,
ModelName=prefix,
ModelState=ModelState,
ModelType=typeof(TModel),
PropertyFilter=propertyFilter,
ValueProvider=valueProvider
};
binder.BindModel(ControllerContext,bindingContext);
returnModelState.IsValid;
}
这个typeof(TModel)形成了只会更新声明范例中有的属性,把它换成model.GetType()就能够办理成绩了,我扩这的这个办法以下
publicstaticclassControllerExtension
{
///<summary>
///更新时是不是依照以后范例举行更新
///</summary>
///<typeparamname="TModel"></typeparam>
///<paramname="controller"></param>
///<paramname="model"></param>
///<paramname="isEx"></param>
publicstaticvoidUpdateModel<TModel>(thisControllercontroller,TModelmodel,boolisExtension)whereTModel:class
{
if(isExtension)
{
Predicate<string>propertyFilter=propertyName=>IsPropertyAllowed(propertyName,null,null);
IModelBinderbinder=ModelBinders.Binders.GetBinder(model.GetType());
ModelBindingContextbindingContext=newModelBindingContext()
{
Model=model,
ModelName=null,
ModelState=controller.ModelState,
ModelType=model.GetType(),
PropertyFilter=propertyFilter,
ValueProvider=controller.ValueProvider
};
binder.BindModel(controller.ControllerContext,bindingContext);
}
else
{
thrownewException("isExtension不克不及选择false");
}
}
privatestaticboolIsPropertyAllowed(stringpropertyName,string[]includeProperties,string[]excludeProperties)
{
boolincludeProperty=(includeProperties==null)||(includeProperties.Length==0)||includeProperties.Contains(propertyName,StringComparer.OrdinalIgnoreCase);
boolexcludeProperty=(excludeProperties!=null)&&excludeProperties.Contains(propertyName,StringComparer.OrdinalIgnoreCase);
returnincludeProperty&&!excludeProperty;
}
}
有了这些,当我们想对新表举行编纂和增加时只必要增加响应的Partial编纂视图就能够了,简化了我们的编程事情。
4、弱点
1、必要依照划定规矩定名,例如说Partial视图必要以响应的类名来定名
2、页面援用是弱范例的
我觉得这个学习方法很重要。初学者应该跟我一样有同样一个毛病。那就是急于求成。很想就自己做出个小小的系统来。可真要动手,却又茫然而不知所措。为什么会这样呢?因为我们没有耐心去学习基础知识。写根本看不到什么效果的测试代码。 |
|