|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
Merge将一定数量的MyISAM表联合而成一个整体,在超大规模数据存储时很有用ado
利用DataReader能够在你的使用程序中做以下事变:
I.不必要缓存数据;
II.处置太年夜而不克不及存储的数据;
III.必要以只进、只读和疾速体例一次性会见数据的。
G.利用一个自界说的强无力的DataSet范例的优点
经由过程创立一个承继于DataSet的子工具,你能够在运转时代实行范例反省和声明。当你有了一个断定的企图大概为你的DataSet有相干的布局,你就能够创立一个用行和列表述一个工具的DataSet。好比,你披露一个消耗者工具的名字属性来代替披露消耗者表的一行中的名字列。有关此节具体信息,请参考微软站点上的文章:WorkingwithaTypedDataSet
H.在自界说的DataSet中处置有效数据
经由过程XSD言语反省你的DataSet确保你的DataSet得当地处置有效援用。nullValue正文使你把BBNull交换成其余字符,String.Empty;大概保存有效援用,抛堕落误提醒,提醒将取决于你使用程序的高低文,默许情形是援用了有效字符。
I.在DataSet中革新数据
假如你要从数据库革新你的DataSet,利用DataAdapter.Fill,假如你的DataTable具有主键,DataAdapter.Fill将依据主键婚配新的行,同时从数据库取值使用到已存在的行。除非已革新行在再次革新前被修正,否者它的RowState将会被设置为UnChanged。注重的是假如DataTable没有设置主键,你的DataSet有大概呈现反复的值。假如你想从数据库革新一个表并保存任何表中行的变动,那末你就要起首添补一个新表,然后使用preserveChanges即是true来兼并谁人DataTable到你的DataSet中往。
J.在DataSet中搜刮数据
当你在一个DataSet中查询特别尺度的行时,使用索引查询将会增添你的查询功能。当你给一个DataTable计划主键时,索引同时也创立了。当你为一个DataTable创立DataView时,索引也同时创立了。以下是利用索引查询的一些情形:
I.假如查询与DataTable中标识主键的列按次相反,利用DataTable.Rows.Find取代DataTable.Select;
II.假如查询包含无主键的列,你可使用DataView为数据的多重查询改良功能。当你在DataView中利用排序时,查询的同时就会创立一个索引。DataView利用Find和FindRows办法查询DataTable中的数据;
IV.假设你不必要表的排序视图,你也能够使用DataView为DataTable创立一个索引查询。注重的是这仅仅在你实行多重查询时才有上风,假如你只是实行一个复杂查询,利用此办法将会下降你的查询效力。
K.DataView的布局
后面也讲过,在给DataTable创立DataView和Sort、RowFilter大概RowStateFilter属性产生变动的同时潜伏的也给DataTable创立了索引。创立DataView工具时,假如Sort、RowFilter和RowStateFilter属性也同时指定,那末索引将只创立一次;假如创立一个空的DataView,那末索引最少被创立两次。
L.页面调剂
ADO.NET使你能够很分明地把持从你的数据库前往甚么样的数据和有几数据存储到一个DataSet。以下没有单一的先容调剂一个查询了局,可是当你计划你的使用程序时应当思索到以下情形:
I.制止在利用DataAdapter.Fill时,在startRecord和maxRecords值上溢出。
II.办理这类成绩的举措是利用WHERE语句、ORDERBY语句和TOP断言。
III.另有一种办理举措是利用TOP断言和嵌套的SELECT声明。好比以下代码:
SELECTTOP10*FROM
(SELECTTOP30*FROMCustomersORDERBYIdASC)ASTable1ORDERBYIdDESC
IV.假如你的日期不是常常改动,你可使用DataSet的存储功效改良实行功能,好比你能够存储相称10页的数据到你的DataSet,然后当用户会见凌驾在存储区的FirstPage和LastPage时才查询数据库以取得新的数据。
M.有企图地添补DataSet
当利用数据添补DataSet时,DataAdapter.Fill办法利用DataSet已有的企图和SelectCommand前往的数据对DataSet举行添补。假如DataSet中没有与之对应的表将会失利,Fill创立一个表,默许情形下,Fill仅仅界说列和列的范例。你能够经由过程设置DataAdapter的MissingSchemaAction属性重载默许的Fill办法。举例,要使Fill办法创立表时老是包括主键信息、独一束缚、列属性、是不是同意空值、列的最年夜长度、只读列和主动增量列,指定DataAdapter.MissingSchemaAction为MissingSchemaAction.AddWithKey。作为选择,你也能够在挪用DataAdapter.Fill之前挪用DataAdpater.FillSchema来包管添补DataSet时企图到位。挪用FillSchema会给数据库增添分外的包袱来输入Schema信息,以是最好的倡议是指定DataSet的企图,大概在挪用Fill之前设置DataAdapter的MissingSchemaAction。
N.利用CommandBuilder
CommandBuilder主动地天生基于DataAdapter的SelectCommand的DataAdapter的InsertCommand、UpdateCommand和DeleteCommand属性。供应SelectCommand实行一个复杂的SELECT,以下信息先容利用CommandBuilder的最好处置。
I.在计划阶段不要利用CommandBuilder,否者发生DataAdapterCommand属性的历程将会遭到搅扰。假如你事后晓得你的UPDATE、INSERT和DELETE声明的内容,你应当分明地指定。一个最好的计划计划是为你的UPDATE、INSERT和DELETE创立存储历程,并在DataAdapter的Command属性中设置和利用它们。
II.CommandBuilder利用SelectCommand决意其他Command属性的值。假如DataAdapter的SelectCommand自己产生变更,应当利用RefreshSchema往革新Command的属性。
III.只需DataAdapter的Command属性为空,CommandBuilder就仅仅创立一个Command,即便你明白地指定Command的属性值,CommandBuilder也不会重写,以是假如你想创立一个Command并保存之前的属性设置,那末就把Command的属性设置为null。
O.SQL的批声明和处置
良多的数据库都撑持在一条命令中利用综合查询或批处置或多便条命令。好比SQLServer中利用“;”。在一条命令中利用综合的多重命令能够无效地削减与数据库之间交互的次数并在你的使用程序中进步效力。好比在你的使用程序中利用批处置完成一切的删除(delete)义务等等。
利用批处置的确进步了效力,但同时也在你的使用程序中办理更新DataSet数据时增添了庞大性。要使得庞大性变复杂化,你就要在你的DataSet中为每一个DataTable创立一个DataAdapter。
P.利用多个表添补一个DataSet
假如你是用批处置从多个表前往数据并把这些数据添补到一个DataSet,fill办法将会利用第一个表的表名定名第一个表,今后的表定名将会接纳在第一个表的表名基本上加上一个递增的数字。举例,上面的代码将慢慢申明fill办法的事情道理:
‘VisualBasic
DimdaAsSqlDataAdapter=NewSqlDataAdapter(“select*fromcustomers;select*fromorders;”,myConnection)
DimdsAsDataSet=NewDataSet()
da.fill(ds,”customers”)
‘C#
SqlDataAdapterda=newSqlDataAdapter(“select*fromcustomers;select*fromorders;”,myConnection);
DataSetds=newDataSet();
da.fill(ds,”customers”);
如下面代码所示,customers表数据将会寄存在一个定名为customers的DataTable中,而orders表数据将会放在一个定名为customers1的DataTable中。固然你也能够在数据添补停止后很简单地修正customers1表属性(TableName)为orders。但是,在今后的数据添补时,只会影响customers表中数据,而orders表将会疏忽并同时创立一个新的定名为customers1的表。要办理这个成绩,你就要在customers1和orders之间创建一个DataTableMapping映照。其他表也云云。举例申明:
‘VisualBasic
DimdaAsSqlDataAdapter=NewSqlDataAdapter("SELECT*FROMCustomers;SELECT*FROMOrders;",myConnection)
da.TableMappings.Add("Customers1","Orders")
DimdsAsDataSet=NewDataSet()
da.Fill(ds,"Customers")
‘C#
SqlDataAdapterda=newSqlDataAdapter("SELECT*FROMCustomers;SELECT*FROMOrders;",myConnection);
da.TableMappings.Add("Customers1","Orders");
DataSetds=newDataSet();
da.Fill(ds,"Customers");
Q.利用DataReader
上面是利用DataReader的一些技能和一些成绩的回覆:
I.在利用相干Command会见任何输入参数之前必需封闭DataReader;
II.在读取数据停止后应该封闭DataReader。假如你的Connection仅仅是用来前往DataReader,那末在封闭DataReader以后你也应当当即封闭它。别的一个封闭Connection的办法是传送CommandBehavior.CloseConnection给ExecuteReader办法。此办法在你从一个办法中前往DataReader而且对这个DataReader没有封闭把持权大概联系关系的毗连时利用时十分有效的。
III.DataReader是为已毗连的数据存取计划;
IV.利用GetString、GetInt32等前往特别数据范例数据;
V.一个毗连只同意利用一个DataReader。在ADO中,假如你只创立一个毗连并利用两个recordsets,一个只读游标和一个只进游标,但实践上,ADO已为你创立了一个隐式的毗连,并在不必的时分隐式地封闭它。ADO.NET中是不可的,你必需为每一个DataReader创立一个Connection,这也是为了让你在利用Connection时赐与更多的把持信息。
VI.默许下,DataReader每次读取时把行中一切的数据装载到内存中。并同意你随机存取以后行中数据。假如随即存取没有需要(没有需要把一切数据都装载到内存),并想进步实行效力,给ExecuteReader办法传送CommandBehavior.SequentialAccess,如许就会改动DataReader的默许举措为仅仅装载哀求的数据到内存。注重的是这类办法请求你按次地存取行中列数据,一旦你略过某一列,今后你将再不会读取到该列的数据。
VII.假如当你在完成从一个DataReader读取数据后,仍旧另有大批未读不必要的数据,这就要在挪用DataReader的Close命令之前挪用Cancel命令。挪用DataReader的Close命令会招致把不必要的数据装载出去并在封闭游标之前清空数据。而挪用Cancel命令就会抛弃这部分数据,从而DataReader在封闭之前就不会读取它们。假如你正在从你的命令前往输入参数,挪用Cancel命令一样会抛弃它们。假如你必要读取任何输入参数,你就不要利用Cancel,而间接利用Close。
R.BLOBs工具
当你利用DataReader读取二进制数据时,你应当传送CommandBehavior.SequentialAccess给ExecuteReader办法挪用。由于DataReader的默许情形是每次读取数据时把每行中一切的数据都存储到内存,而二进制数据又十分的年夜,了局就会使大批的内存空间被一个单一的BLOB占用。SequentialAccess使得你的DataReader默许举动为仅读取必要的数据。然后你就能够利用GetBytes大概GetChars决意一次读取几数据。
记着的是利用SequentialAccess后,你不克不及序次倒置地会见DataReader中分歧的字段。就是说,假如你的查询前往三列,个中第三列是BLOB数据范例,假如你想会见第三列数据,那末你就必需先会见第一列,然后是第二列,再然后才是第三列的BLOB数据。这是由于此时前往的数据是有序的,并且一旦你跳过某一列,再回过火来读取这一列是不可的。
S.利用命令
ADO.NET供应了实行命令的几种分歧办法,同时也供应了优化实行命令的几种分歧参数。上面将要先容的是选择最好实行命令的技能和改良一个可实行命令的功能。
I.OleDbCommand最好理论
.NET框架中各类数据供应者之间的实行命令尺度几近是一样的。可是也有分歧,上面是实行OleDbCommand的一些技能:
①利用CommandType.Text挪用存储历程,利用CommandType.StoredProcedure天生;
②断定设置OleDbParameter的范例、巨细(假如请求)和精度(假如是数字大概小数),注重的是,假如你不明白设置OleDbParameter,OleDbCommand将会为你的实行命令从头天生OleDbParameter。
II.SqlCommand最好理论
利用SqlCommand疾速实行存储历程:假如你要挪用一个存储历程,指定SqlCommand的CommandType为存储历程的CommandType。如许在实行命令时,就会提交此命令是挪用存储历程,从而到达疾速实行。
III.利用已筹办的办法
Command.Prepare办法优化你的参数化实行命令。Prepare布局为多重挪用最优化指天命令。要利用Prepare,你起首得了解你的数据库是如何响应Prepare挪用。SQLServer2000中,Command已被隐式优化和Prepare不是必需的;在SQLServer7.0或别的数据库中利用Prepare是无效的。
IV.明白地指定企图和元数据
ADO.NET中的良多工具都要揣度元数据信息,只需用户不指定它,举比方下:
①假如在DataSet中不存在,DataAdapter.Fill办法就会创立表和列信息;
②CommandBuilder为自力表的Select命令天生DataAdpater命令参数;
③CommandBuilder.DeriveParameters组装一个命令工具的参数信息;
假如甚么时分都利用下面讲的办法,大概会下降实行功能。保举在计划阶段和告白段使用程序中利用。大概的情形下,一样平常都要指定企图和元数据。这些包含指定DataSet的表和列、指定DataAdapter的Command属性和指定Command的参数信息。
V.ExecuteScalar和ExecuteNonQuery
假如你想只前往一个复杂值,好比Count(*)、Sum(Price)大概Avg(Quantity),你可使用ExecuteScalar,它匡助你一步到位失掉你想要的值,从而制止利用DataReader的两步盘算(ExecuteReader+GetValue);
当你不想前往行信息,好比修正数据(INSERT、UPDATE、DELETE)大概仅必要输入参数大概前往值,利用ExecuteNonQuery,它往失落不用要的处置创立一个空的DataReader。
VI.空值反省
假如在你的表中某列同意空值,你可使用Where语句举行空值反省,上面举例申明:
select*fromcustomerswhere((LastName=@LastName)or(LastNameISNULLand@LastNameISNULL))
下面语句反省了列是不是为空和参数是不是为空。
VII.传送null参数值
当你在命令中传送null参数值给数据库时,你不克不及利用null(Nothing在vb中),应当利用DBNull.Value。举例:
‘vb
DimparamAsSqlParameter=NewSqlParameter(“@Name”,SqlDbType.NVarChar,20)
param.Value=DBNull.Value
‘C#
SqlParameterparam=newSqlParameter(“@Name”,SqlDbType.NVarChar,20);
param.Value=DBNull.Value;
VIII.利用事件处置
ADO.NET中的事件处置模子已改动,在ADO中,一旦StartTransaction被挪用,任何事件下的更新都被以为是事件的一部分。但是,在ADO.NET中,当Connection.BeginTransaction被挪用,前往一个命令联系关系的事件工具(事件属性是由命令的事件属性指定的)。如许包管让你在一个Connection中实行多个事件。假如命令的Command.Transaction属性与入手下手的事件纷歧致,命令就不会完成并抛堕落误。
IX.利用Connections
高效力的使用程序应当利用起码的工夫与数据库创建毗连,好比利用ConnectionPooling等。上面将先容怎样利用ADO.NET创建高效力使用的一些数据库方面的技能。
①ConnectionPooling
在SQLServer、OLEDB和.NET框架布局中的DataProvider中,都供应了隐式的毗连池毗连撑持。你能够在ConnectionString中指定分歧的参数值把持毗连池的举动。好比上面的例子使OLEDB的毗连池有效并主动地举行事件处置:
Provider=SQLOLEDB;OLEDBServices=-4;DataSource=localhost;IntegratedSecurity=SSPI;
在SQLServer.NETDataProvider中供应了以下参数设置把持毗连池的举动:ConnectionLifttime、ConnectionReset、Enlist、MaxPoolSize、MinPoolSize和Pooling。
②利用DataAdapter最优化毗连
利用DataAdpater的Fill和Update办法时会主动地翻开响应的毗连。假如Fill大概Update翻开一个毗连,在它操纵完成后它会封闭此毗连。最好的实行体例是在你必要的时分才创建毗连。同时削减多个操纵时翻开和封闭毗连的次数。
保举你在仅仅实行一个Fill大概Update时,同意Fill大概Update办法隐式地翻开和封闭毗连;假如你要实行多个Fill大概Update,倡议你显式地创建毗连、实行Fill大概Update操纵然后显式地封闭毗连。
分外地,在我们实行事件处置时,在入手下手事件之前应当显式地创建毗连,并在事件停止后显式地封闭毗连。举例:
‘VisualBasic
PublicSubRunSqlTransaction(daAsSqlDataAdapter,myConnectionAsSqlConnection,dsAsDataSet)
myConnection.Open()
DimmyTransAsSqlTransaction=myConnection.BeginTransaction()
myCommand.Transaction=myTrans
Try
da.Update(ds)
myTrans.Commit()
Console.WriteLine("Updatesuccessful.")
CatcheAsException
Try
myTrans.Rollback()
CatchexAsSqlException
IfNotmyTrans.ConnectionIsNothingThen
Console.WriteLine("Anexceptionoftype"&ex.GetType().ToString()&_
"wasencounteredwhileattemptingtorollbackthetransaction.")
EndIf
EndTry
Console.WriteLine("Anexceptionoftype"&e.GetType().ToString()&"wasencountered.")
Console.WriteLine("Updatefailed.")
EndTry
myConnection.Close()
EndSub
‘C#
publicvoidRunSqlTransaction(SqlDataAdapterda,SqlConnectionmyConnection,DataSetds)
{
myConnection.Open();
SqlTransactionmyTrans=myConnection.BeginTransaction();
myCommand.Transaction=myTrans;
try
{
da.Update(ds);
myCommand.Transaction.Commit();
Console.WriteLine("Updatesuccessful.");
}
catch(Exceptione)
{
try
{
myTrans.Rollback();
}
catch(SqlExceptionex)
{
if(myTrans.Connection!=null)
{
Console.WriteLine("Anexceptionoftype"+ex.GetType()+
"wasencounteredwhileattemptingtorollbackthetransaction.");
}
}
Console.WriteLine(e.ToString());
Console.WriteLine("Updatefailed.");
}
myConnection.Close();
}
X.老是封闭Connections和DataReaders
在你利用完Connection大概DataReader工具后,你应当明白地封闭它们。体系中的碎片收拾程序只是在最初必要的时分才举行收拾,而一些很耗资本的毗连还得由你本人来开释。同时假如你不明白地封闭毗连,此毗连就有大概不前往毗连池,除非毗连池的MaxPoolSize已到达而且此毗连还仍旧无效。
注重:在你的类的Finalize办法中不要利用Close大概Dispose使用到一个Connection大概一个DataReader大概任何被办理工具上。在一个Finalizer中,仅仅开释你的类间接具有的没法办理的资本。假如你的类不具有任何没法办理的资本,就不要在你的类利用Finalize办法。
XI.在C#中利用Using声明
在C#中,一个十分便当的包管封闭你利用过的Connection和DataReader工具的办法是利用Using声明。当工具超越了它的利用局限,Using声明就会主动地开释该工具。举例:
‘C#
stringconnString="DataSource=localhost;IntegratedSecurity=SSPI;InitialCatalog=Northwind;";
using(SqlConnectionconn=newSqlConnection(connString))
{
SqlCommandcmd=conn.CreateCommand();
cmd.CommandText="SELECTCustomerId,CompanyNameFROMCustomers";
conn.Open();
using(SqlDataReaderdr=cmd.ExecuteReader())
{
while(dr.Read())
Console.WriteLine("{0} {1}",dr.GetString(0),dr.GetString(1));
}
}
Using声明在VisualBasic.Net中不成用。
XII.制止会见OleDbConnection.State属性
假如你必要常常反省State属性,最幸亏OleDbConnection上监听StateChange事务。上面的代码演示当OleDbConnection.State产生变更时利用StateChange向把持台发送一条动静:
‘VisualBasic
AddHandlernwindConn.StateChange,NewStateChangeEventHandler(AddressOfOnStateChange)
ProtectedSharedSubOnStateChange(senderAsObject,argsAsStateChangeEventArgs)
Console.WriteLine("ThecurrentConnectionstatehaschangedfrom{0}to{1}.",_
args.OriginalState,args.CurrentState)
EndSub
‘C#
nwindConn.StateChange+=newStateChangeEventHandler(OnStateChange);
protectedstaticvoidOnStateChange(objectsender,StateChangeEventArgsargs)
{
Console.WriteLine("ThecurrentConnectionstatehaschangedfrom{0}to{1}.",
args.OriginalState,args.CurrentState);
}
ADO.NET最好理论(下)
http://www.csdn.net/Develop/read_article.asp?id=22664
这能找出所有错误的99.99%。它不能找出的是仅仅涉及数据文件的损坏(这很不常见)。如果你想要检查一张表,你通常应该没有选项地运行myisamchk或用-s或--silent选项的任何一个。 |
|