|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
据说很厉害,甚至可以把C#也干掉^_^,不过也很复杂,本来C++已经够复杂的。有人甚至还提出把这个东东引进标准,我觉得基本上不可能的。ado|编程|数据|数据库 概述
ADO.NET为我们供应了壮大的数据库开辟才能,它内置的多个工具为我们的数据库编程供应了分歧的选择。可是在同意我们天真选用的同时,很多初学者也很利诱,我究竟是应当利用DataReader仍是应当利用DataAdapter?我只想读取一小部分数据,岂非我必定要Fill满全部DataSet吗?为何DataReader不克不及和RecordSet一样供应一个数据更新的办法?DataSet究竟有甚么优点?
在本文中,我将对.netPetShop的数据库编程形式和Duwamish的数据库编程形式举行一些复杂的剖析和对照。假如您也有以上疑问的话,信任在读完本文以后,就能够依据详细的必要来制订一个最合适您使用的数据库编程形式。
.NetPetShop和Duwamish复杂先容
信任人人必定传闻过着名的"宠物店年夜战",没错,本文的配角之一就是得胜方.NetPetShop,微软号称以27倍的速率和1/4的代码量远远抢先于基于J2EE的PetStore宠物商铺。固然SUN也曾对此埋怨过不满,求全谴责此"年夜战"有水份,不外不管怎样,.NetPetShop相对是一个典范的.Net实例教程,最少为我们供应了一条赶超J2EE的“捷径=":),它的下载地点是:http://www.gotdotnet.com/team/compare
.NetPetShop宠物网上商铺首页
而Duwamish则是一个表面复杂,外部却极为庞大的一个网上书店的.Net完全使用典范,作为一个微软官方的Sample,它同时供应了C#和VB.Net两种言语版本,而且还附上了大批细致的中文材料,假如打印出来,其实是居家游览,临睡进厕必备之物。甚么?您没传闻过?呵呵,假如您装了VisualStudio.Net的话,它就在您的硬盘上悄悄的躺着呢,不外还没有被安装,您能够在您的VS.net的EntERPriseSamples目次下找到并安装它,比方:C:ProgramFilesMicrosoftVisualStudio.NETEnterpriseSamplesDuwamish7.0CS。
布局简述
两家商铺都接纳了n层使用布局(毫无疑问,n层布局的使用架构应当相对是您开辟.Net使用的首选,哪怕您只想做一个网页计数器),分歧的是,PetShop接纳的是最多见的三层使用布局,分离为暗示层,两头层和数据层。而Duwamish则接纳的是一个四层使用布局,并利用分歧的项目分开开,分离为暗示层,营业表面层,营业划定规矩层和数据层。至于这两种布局分离有甚么长处和弱点,和为何要这么分层,我们不举行具体会商,由于本文的重点不在于此。我们次要剖析的是他们的数据库编程的形式。
Duwamish数据会见分析
起首,我们来看看Duwamish书店,它接纳的是DataAdapter和DataSet共同的数据存储形式,所分歧的是,它对DataSet举行子类化扩大作为数据载体,也就是接纳定制的DataSet来举行层间的数据传输,上面是一个定制的DataSet示例:
publicclassBookData:DataSet
{
publicBookData()
{
//
//Createthetablesinthedataset
//
BuildDataTables();
}
privatevoidBuildDataTables()
{
//
//CreatetheBookstable
//
DataTabletable=newDataTable(BOOKS_TABLE);
DataColumnCollectioncolumns=table.Columns;
columns.Add(PKID_FIELD,typeof(System.Int32));
columns.Add(TYPE_ID_FIELD,typeof(System.Int32));
columns.Add(PUBLISHER_ID_FIELD,typeof(System.Int32));
columns.Add(PUBLICATION_YEAR_FIELD,typeof(System.Int16));
columns.Add(ISBN_FIELD,typeof(System.String));
columns.Add(IMAGE_FILE_SPEC_FIELD,typeof(System.String));
columns.Add(TITLE_FIELD,typeof(System.String));
columns.Add(DESCRIPTION_FIELD,typeof(System.String));
columns.Add(UNIT_PRICE_FIELD,typeof(System.Decimal));
columns.Add(UNIT_COST_FIELD,typeof(System.Decimal));
columns.Add(ITEM_TYPE_FIELD,typeof(System.String));
columns.Add(PUBLISHER_NAME_FIELD,typeof(System.String));
this.Tables.Add(table);
}
………
}
我们能够看到它有一个BuildDataTables办法,而且在机关函数中挪用,如许,定制的Books表就和这个DataSet绑缚在一同了,免得今后还要举行ColumnMapping,这真是个好主张,我怎样就没有想到呢?:)
办理了数据布局,接上去看看数据层的代码完成,在Duwamish中,数据层中有5个类,分离是Books,Categories,Customers和Orders,每一个类分离只卖力有关数据的存取。上面是个中一个类的示例代码:
privateSqlDataAdapterdsCommand;
publicBookDataGetBookById(intbookId)
{
returnFillBookData("GetBookById","@BookId",bookId.ToString());
}
privateBookDataFillBookData(StringcommandText,StringparamName,StringparamValue)
{
if(dsCommand==null)
{
thrownewSystem.ObjectDisposedException(GetType().FullName);
}
BookDatadata=newBookData();
SqlCommandcommand=dsCommand.SelectCommand;
command.CommandText=commandText;
command.CommandType=CommandType.StoredProcedure;//usestoredprocforperf
SqlParameterparam=newSqlParameter(paramName,SqlDbType.NVarChar,255);
param.Value=paramValue;
command.Parameters.Add(param);
dsCommand.Fill(data);
returndata;
}
这里就是数据层的代码了,我们在这里能够看到Duwamish接纳了DataAdapter来将数据添补到定制的DataSet中,然后前往该DataSet。我感应很奇异的是在数据存取层中居然能够看到GetBookById如许详细的数据存取办法,固然最初仍是有一个笼统出来的FillBookData办法,可是下面另有三层啊,底层都做到这份上了,那下层都做些甚么呢?谜底是数据反省,下层基础上都在做一些很周密的数据正当性校验(固然也会包含一些对照庞大的事件逻辑,可是其实不多),示例代码以下:
publicCustomerDataGetCustomerByEmail(StringemailAddress,Stringpassword)
{
//
//Checkpreconditions
//
ApplicationAssert.CheckCondition(emailAddress!=String.Empty,"Emailaddressisrequired",
ApplicationAssert.LineNumber);
ApplicationAssert.CheckCondition(password!=String.Empty,"Passwordisrequired",
ApplicationAssert.LineNumber);
//
//GetthecustomerdataSet
//
CustomerDatadataSet;
using(DataAccess.CustomerscustomersDataAccess=newDataAccess.Customers())
{
dataSet=customersDataAccess.LoadCustomerByEmail(emailAddress);
}
//
//Verifythecustomerspassword
//
DataRowCollectionrows=dataSet.Tables[CustomerData.CUSTOMERS_TABLE].Rows;
if((rows.Count==1)&&rows[0][CustomerData.PASSWORD_FIELD].Equals(password))
{
returndataSet;
}
else
{
returnnull;
}
}
在这个办法中,真正举行数据存取的实践上只要
dataSet=customersDataAccess.LoadCustomerByEmail(emailAddress);
这么一句,是间接挪用的数据层。别的都是在举行正当性校验,我们能够感悟到,举行一个真实的企业级开辟必要思索的体系强健性有何等主要。
.netPetShop数据会见分析
OK,Duwamish看完了,上面我们来看看PetShop的数据会见机制。
PetShop只要一个项目,它接纳的分层举措是将两头层和数据层都写成cs文件放在Components目次里,个中数据层就是一个名为Database的类,它封装了一切对数据库的底层操纵。上面是示例代码段:
publicvoidRunProc(stringprocName,outSqlDataReaderdataReader){
SqlCommandcmd=CreateCommand(procName,null);
dataReader=cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
}
我们看到了一个跟Duwamish一模一样的另外一种数据会见体例,它将一切的数据会见办法笼统出来做成一个RunProc办法,至于前往数据呢,呵呵,它有点偷懒,间接前往一个DataReader给你,你本人往读吧。还记得Duwamish接纳的层间数据传输载体是甚么吗?对了,是DataSet,它被数据层添补后前往给了两头层。可是这里,数据层和传输层的数据传输载体酿成了DataReader,实践上,还不克不及称它为数据载体,由于数据还没入手下手读呢,在这里,DataReader的感化和指针有点相似,大概我们应当称它为“数据援用”:)
接着往下看,DataReader被怎样“处置”的:
publicProductResults[]GetList(stringcatid,intcurrentPage,intpageSize,refintnumResults)
{
numResults=0;
intindex=0;
SqlDataReaderreader=GetList(catid);
ProductResults[]results=newProductResults[pageSize];
//nowloopthroughthelistandpulloutitemsofthespecifiedpage
intstart=(int)((currentPage-1)*pageSize);
if(start<=0)start=1;
//skip
for(inti=0;i<start-1;i++){
if(reader.Read())numResults++;
}
if(start>1)reader.Read();
//readthedataweareinterestedin
while(reader.Read()){
if(index<pageSize){
results[index]=newProductResults();
results[index].productid=reader.GetString(0);
results[index].name=reader.GetString(1);
index++;
}
numResults++;
}
reader.Close();
//seeifneedtoredimarray
if(index==pageSize)
returnresults;
else{
//notafullpage,redimarray
ProductResults[]results2=newProductResults[index];
Array.Copy(results,results2,index);
returnresults2;
}
}
注重到currentPage和pageSize了吗?本来在这里就举行了数据分页,只前往满意必要的起码的数据量,而不是象我们良多喜好偷懒的人一样,复杂的将全部DataTable一股脑的绑定到DataGrid,形成大批的数据冗余。
在这里,数据被真实的读出来,而且被手动添补到一个自界说的工具数组中,我们来看看这个数组的界说:
publicclassProductResults
{
privatestringm_productid;
privatestringm_name;
//productprops
publicstringproductid{
get{returnm_productid;}
set{m_productid=value;}
}
publicstringname{
get{returnm_name;}
set{m_name=value;}
}
}
十分之复杂,不外我有点奇异为何不利用struct呢?是否是.Net中struct和class的功能差异已能够疏忽不计了?
剖析总结
经由过程察看这两个商铺的详细完成,我们失掉了两个分歧的数据会见形式,Duwamish接纳的是以DataSet为中心,由于DataSet供应了这方面大批的相干办法,以是全部使用的数据传输,数据格局界说,数据校验都环绕着DataSet来举行,全部架构界说十分明晰和松散,可是却显得有些复杂。PetShop在全部程序中没有接纳一个DataSet,程序十分的简便,轻灵,可是没有Duwamish那末强的强健性。这两个程序是Microsoft公司分歧的小组写出来的代码,以是有着分歧作风。不外都应当能代表.Net的尺度形式。看到这里,你应当对文章开首提出的那些疑问有一个对照抽象的熟悉了吧。
别的,请再次注重,PetShop在翻开数据毗连以后,并没有即刻读取数据,而是将DataReader传送给别的的工具来实行数据读的操纵,然后才封闭毗连。如许,数据毗连的工夫加长了,而数据库毗连是一项十分可贵的服务器资本,比拟之下,Dawamish在毗连数据库以后即刻举行添补,然后敏捷开释失落数据库毗连的体例加倍有益于大批用户的并发会见。
再一点,上文的程序中没有提到更新操纵,PetShop接纳的是利用Command工具实行单个存储历程的体例来举行更新操纵,是属于一种在线立即数据更新形式。而Dawamish接纳的是DataAdapter的Update办法,将DataSet的改动一次性的提交到数据库中,属于离线数据更新形式。这类形式的优点是能够一次性更新多量量数据,削减数据库的毗连次数。弱点是假如数据库在修改十分频仍的情形下必要及时的跟踪数据变更就分歧适了。必要依据详细的情形接纳详细的数据更新举措。
总的来讲,假如您只必要疾速的读取数据并显现出来,保举您接纳DataReader,假如您必要对数据举行大批的修正,另有大批并发会见的大概,并且不必要及时的跟踪数据库的变更,保举您利用DataSet。固然,这两种情形有点极度了,实践的使用情况大概有着很庞大的前提,详细必要您本人审时度势,综合接纳,不外我团体仍是对照喜好PetShop那种轻灵的作风:)
本文只实验对以上两个典范的.Net使用例程的数据会见机制做了一个复杂的追踪剖析。
我也不知道,我原来理解的,NET就是C++编程,只是与JAVA相对,呵呵。以为.ET就是高级C++编程。 |
|