A summary of sqldatareader, sqldataadapter, and sqlcommand.

Source: Internet
Author: User

1. sqldatareader: for online applications, conn. open () is required. Close it after use.

Sqlconnection conn = new sqlconnection (connstr );
// Conn. open ();
Sqlcommand cmd = new sqlcommand ("select top 10 * From Tuser", Conn );
Sqldatareader reader = cmd. executereader (commandbehavior. closeconnection );
While (reader. Read ())
{
Console. writeline (reader. getvalue (2 ));
}
This sectionCodeError: executereader requires an open and available connection. The connection's current state is closed.
You should open conn. open.

2. sqldataadapter,Offline Application,You do not need to use conn. open (). It encapsulates this function into itself and does not need to be explicitly called. It directly fills the data into dataset.

Like commands in the ADO age, sqldataadapter is a new thing in ADO. net. It is used with dataset. In fact, dataset is like a small database residing in the memory. In dataset, there can be multiple datatables, which can be associated with each other, just like table Association in the database! Sqldataadapter extracts data from the database and stores it in dataset. When the data in dataset changes, sqldataadapter updates the data in the database, to ensure that the data in the database is consistent with the data in dataset!
In the words of Microsoft consultants: dataadapter is like a shovel, which is responsible for "Shovel" data from the database to dataset, or "Shovel" data from dataset to the database!

When you call the fill method of dataadapter, it will open sqlconnection to the database, and then execute the command by creating a sqlcommand and calling executereader. Then, it will use the sqldatareader created by an implicit principal, read data from the database. After the row is read, sqldatareader and sqlconnection are closed.

Defaultview is an attribute of the able class. You can use the dataview class to define multiple views for each able.

Use recyclter to check the original code of sqldataadapter and its parent class. The method calling process is as follows:

Fill (Dataset dataset)->

Fill (dataset, 0, 0, "table", selectcommand, fillcommandbehavior)->

Fillinternal (dataset, null, startrecord, maxrecords, srctable, command, behavior)->

Fill (dataset, srctable, reader, startrecord, maxrecords)->

Fill (dataset, srctable, reader, startrecord, maxrecords)->

Fillfromreader (dataset, null, srctable, container, startrecord, maxrecords, null, null)->

Fillloaddatarow (mapping)->

While (datareader. Read ())

Therefore, I personally think that the essence of the sentence is: sqldataadapter internal data acquisition is achieved by calling sqldatareader, and both must use sqlconnection and sqlcommand.

 

For details, refer to the original code of sqldataadapter and its parent class as follows:

2.1 sqldataadapter is a subclass of dbdataadapter.

Public sealed class sqldataadapter: dbdataadapter, idbdataadapter, idataadapter, icloneable

2.2 dbdataadapter is an abstract class that contains the specific implementation of fill.

public abstract class dbdataadapter: dataadapter, idbdataadapter, idataadapter, icloneable
{< br> Public override int fill (Dataset dataset)
{< br> int num;
intptr;
bid. scopeenter (Out PTR, " % d #, dataset \ n ", base. objectid);
try
{< br> idbcommand selectcommand = This. _ idbdataadapter. selectcommand;
commandbehavior fillcommandbehavior = This. fillcommandbehavior;
num = This. fill (dataset, 0, 0, "table", selectcommand, fillcommandbehavior);
}< br> finally
{< br> bid. scopeleave (ref PTR);
}< br> return num;
}

Protected virtual int fill (Dataset dataset, int startrecord, int maxrecords, string srctable, idbcommand command, commandbehavior behavior)
{
Int num;
Intptr;
Bid. scopeenter (Out PTR, "<comm. dbdataadapter. fill | API> % d #, dataset, startrecord, maxrecords, srctable, command, behavior = % d {Ds. commandbehavior} \ n ", base. objectid, (INT) behavior );
Try
{
If (Dataset = NULL)
{
Throw ADP. fillrequires ("dataset ");
}
If (startrecord <0)
{
Throw ADP. invalidstartrecord ("startrecord", startrecord );
}
If (maxrecords <0)
{
Throw ADP. invalidmaxrecords ("maxrecords", maxrecords );
}
If (ADP. isempty (srctable ))
{
Throw ADP. fillrequiressourcetablename ("srctable ");
}
If (command = NULL)
{
Throw ADP. missingselectcommand ("fill ");
}
Num = This. fillinternal (dataset, null, startrecord, maxrecords, srctable, command, behavior );
}
Finally
{
Bid. scopeleave (ref PTR );
}
Return num;
}

Private int fillinternal (Dataset dataset, datatable [] datatables, int startrecord, int maxrecords, string srctable, idbcommand command, commandbehavior behavior)
{
Bool flag = NULL = command. connection;
Try
{
Idbconnection connection = getconnection3 (this, command, "fill ");
Connectionstate open = connectionstate. open;
If (missingschemaaction. addwithkey = base. missingschemaaction)
{
Behavior | = commandbehavior. keyinfo;
}
Try
{
Quietopen (connection, out open );
Behavior | = commandbehavior. sequentialaccess;
Using (idatareader reader = NULL)
{
Reader = command. executereader (behavior );
If (datatables! = NULL)
{
Return this. Fill (datatables, reader, startrecord, maxrecords );
}
Return this. Fill (dataset, srctable, reader, startrecord, maxrecords );
}
}
Finally
{
Quietclose (connection, open );
}
}
Finally
{
If (FLAG)
{
Command. Transaction = NULL;
Command. Connection = NULL;
}
}

Protected virtual int fill (Dataset dataset, string srctable, idatareader datareader, int startrecord, int maxrecords)
{
Int num;
Intptr;
Bid. scopeenter (Out PTR, "<comm. dataadapter. Fill | API> % d #, dataset, srctable, datareader, startrecord, maxrecords \ n", this. objectid );
Try
{
If (Dataset = NULL)
{
Throw ADP. fillrequires ("dataset ");
}
If (ADP. isempty (srctable ))
{
Throw ADP. fillrequiressourcetablename ("srctable ");
}
If (datareader = NULL)
{
Throw ADP. fillrequires ("datareader ");
}
If (startrecord <0)
{
Throw ADP. invalidstartrecord ("startrecord", startrecord );
}
If (maxrecords <0)
{
Throw ADP. invalidmaxrecords ("maxrecords", maxrecords );
}
If (datareader. isclosed)
{
Return 0;
}
Datareadercontainer Container = datareadercontainer. Create (datareader, this. returnproviderspecifictypes );
Num = This. fillfromreader (dataset, null, srctable, container, startrecord, maxrecords, null, null );
}
Finally
{
Bid. scopeleave (ref PTR );
}
Return num;
}

Internal int fillfromreader (Dataset dataset, datatable, string srctable, datareadercontainer datareader, int startrecord, int maxrecords, datacolumn parentchaptercolumn, object parentchaptervalue)
{
Int num2 = 0;
Int schemacount = 0;
Do
{
If (0 <datareader. fieldcount)
{
Schemamapping mapping = This. fillmapping (dataset, datatable, srctable, datareader, schemacount, parentchaptercolumn, parentchaptervalue );
Schemacount ++;
If (mapping! = NULL) & (mapping. datavalues! = NULL) & (mapping. datatable! = NULL ))
{
Mapping. datatable. beginloaddata ();
Try
{
If (1 = schemacount) & (0 <startrecord) | (0 <maxrecords )))
{
Num2 = This. fillloaddatarowchunk (mapping, startrecord, maxrecords );
}
Else
{
Int num3 = This. fillloaddatarow (Mapping );
If (1 = schemacount)
{
Num2 = num3;
}
}
}
Finally
{
Mapping. datatable. endloaddata ();
}
If (datatable! = NULL)
{
Return num2;
}
}
}
}
While (this. fillnextresult (datareader ));
Return num2;
}

Private int fillloaddatarow (schemamapping mapping)
{
Int num = 0;
Datareadercontainer datareader = mapping. datareader;
If (! This. _ hasfillerrorhandler)
{
While (datareader. Read ())
{
Mapping. loaddatarow ();
Num ++;
}
Return num;
}
While (datareader. Read ())
{
Try
{
Mapping. loaddatarowwithclear ();
Num ++;
Continue;
}
Catch (exception)
{
If (! ADP. iscatchableexceptiontype (exception ))
{
Throw;
}
ADP. traceexceptionforcapture (exception );
This. onfillerrorhandler (exception, mapping. able, mapping. datavalues );
Continue;
}
}
Return num;
}

}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.