Introduction to unified data access
Unified Data Access (UDA) is used to isolate systems and data platforms, so that the system can be freely transplanted on various database platforms. The database access interface requires that standard SQL statements be submitted to the database access module through this interface, not just statements that are valid for the current database.
Unified data access and data layer separation are two concepts and practices that complement each other. Unified Data Access provides the database access environment and interface independence for data layer separation, interface-driven, and data layer architecture. consistency is guaranteed.
Uniform Data Access is automatically packaged inside ADO. net. The specific database used is defined by the system administrator in the configuration file. The unified data access interface provides internal management of database connection objects, Data command objects, transaction objects, etc. Therefore, the client does not need to manage these objects on its own, but only needs to submit database commands.
The main data structure in UDA is "result data ". Result data is the packaging of database operation results. For a query command, an idatareader object, a DataSet object, a able object, an idictionary object, an ilist object, and a data object (the data structure defined in Data Object Management) may be returned) or a simple result. Of course, the user can request to return data in XML format.
Agileeas. NET provides the idataaccessor and idataconntion interfaces:
Idataaccessor provides two basic operations for data: query results and SQL statement execution. It also provides SQL batch processing, proxy query, and transaction delegate operations, idataconnetion provides a database execution environment for idataaccessor.
Idataaccessor is an interface for unified data access. It exists in the idataaccessor database environment, the client only needs to use the methods provided by the accessor and provide appropriate parameters for these methods for database operations. The accessors automatically create database commands on the current database connection and encapsulate the returned results.
Currently, SQL databases (sqlserverconnection and sqlserveraccessor), oledbconnection and oledbaccessor, and ODBC databases (odbcconnection and odbcaccessor) are implemented. Oracle databases are accessed by individual databases.ProgramSet implementation.
Explain query and execute
The preceding section briefly introduces the UDA and its two most important interfaces. Among the two interfaces, the idataaccessor interface is responsible for data operation, the two most important overload Methods query and execute are defined.
Let's take a look at the query overload:
/// <Summary>
/// Execute the given database query command.
/// </Summary>
/// <Param name = "commandstring"> command statement to be executed. </Param>
/// <Param name = "commandtype"> type of the command to be executed. </Param>
/// <Param name = "Parameters"> parameters required for command execution. </Param>
/// <Param name = "resulttype"> type of the returned result requested by the caller. </Param>
/// <Returns> returns the queried data result. </Returns>
Object Query (string commandstring, system. Data. commandtype, parametercollection parameters, EAS. Data. Access. resulttype );
In agileeas. in. net, query only provides one method for different return types. Different query results are returned Based on the return type of the last parameter. Therefore, an equipment operation is generated, and the upper-layer callers need to solve the unpacking problem, let's take a look at the return type:
Default: default. This type of result is generally used to return a single query value or an aggregate value (such as the value of Count, Max, etc ).
Datareader: returns an idatareader object. Because the access to the idatareader object database is connection-oriented, and the query method internally complies with the previous iconnection operation mode, if you want to return an idatareader, you must enable the corresponding iconnection before calling the query method, and disable iconnection after the idatareader operation is complete. Otherwise, iconnection is disabled before the query method is returned, causing the idatareader to become unavailable. You can use the datareaderhandler delegate to solve this problem.
Dataset: returns a system. Data. DataSet object. Used to obtain a non-connection-oriented data set.
Datatable: returns a system. Data. datatable object. Used to obtain a non-connection-oriented data set.
Dictionary: returns an idictionary interface set object. Used to obtain a non-connection-oriented database record. The field mapped to the dictionary key.
List: returns a system. Collections. ilist object. Used to obtain a set of non-connection-oriented database records. Each record has only one field.
Next let's take a look at the execute overload:
/// <Summary>
/// Execute the specified non-query command.
/// </Summary>
/// <Param name = "commandstring"> command statement to be executed. </Param>
/// <Param name = "commandtype"> command type to be executed. </Param>
/// <Param name = "Parameters"> set of parameters of the command to be executed. </Param>
/// <Returns> returns the number of lines affected by the command. </Returns>
Int execute (string commandstring, system. Data. commandtype, parametercollection parameters );
Execute directly returns the number of rows affected by the query.
Data Processing Process
Agileeas. NET platform sets a principle when accessing the database: idataaccessor should not change the idataconnetion status at will. We know that the database operation needs to be enabled and disabled when accessing the database, therefore, when idataaccessor executes the SQL command, it first checks whether idataconnetion is enabled. If not, it executes idataconnetion. open () and perform idataconnetion after the SQL statement is executed. close ().
Bool open = This. Connection. isopen;
If (! Open)
This. Connection. open ();
Try
{
// Execute SQL
}
Finally
{
If (! Open)
This. Connection. Close ();
}
Delegated Query
When executing the query command, there is a returned result idatareader, which requires the database to remain open. Therefore, we added a delegate method delegatequery, which is defined as follows:
/// <Summary>
/// Define the data access delegate when the result is returned using datareader.
/// </Summary>
/// <Remarks>
/// The instance of the delegate can be called internally by the accessor. delegatequery method. Therefore, you do not need to consider disabling datareader for the delegate instance.
/// </Remarks>
Public Delegate void datareaderhandler (system. Data. idatareader datareader );
If a programmer needs to return the idatareader type processing result without processing the open or close operations of the database during the development process, it can use the following form of processing:
Private void button3_click (Object sender, eventargs E)
{
Idataaccessor dataaccessor = new oledbconnection (). createdataaccessor ();;
Dataaccessor. delegatequery (New datareaderhandler (loadtoui), "select * From Table1 ");
}
Private void loadtoui (idatareader reader)
{
While (reader. Read ())
{
// BusinessCode
}
}
Transaction delegate
In the database transaction section, apart from opening and closing the transaction normally, I recommend a transaction delegate and method for execution. idataaccessor provides the transactionexecute method, definition of its delegate transactionhandler:
/// <Summary>
/// Define the transaction processing delegate for database operations. This delegate will execute database transactions on behalf of the customer, so that the user does not need to consider the start and end of the transaction.
/// </Summary>
Public Delegate int transactionhandler (idataaccessor accessor );
The following is a routine:
Private void button3_click (Object sender, eventargs E)
{
Idataaccessor dataaccessor = new oledbconnection (). createdataaccessor ();;
Dataaccessor. transactionexecute (New transactionhandler (savedata ));
}
Private int savedata (idataaccessor accessor)
{
Int iaff = 0;
Iaff + = accessor. Execute ("...");
//
Iaff + = accessor. Execute ("...");
Return iaff;
}
Obtain UDA object
The idataconnection object in UDA inherits from the EAS. Sessions. isessionresource interface. That is to say, the data connection in UDA is also a session resource, which can be read through the Conference provided by the context:
// Get the current session connection
Idataconnection dbcn = session. resouces. findresources (typeof (idataconnection) [0] As idataconnection;
// Accessors
Idataaccessor dataaccessor = dataconnection. createdataaccessor ();
You can also directly obtain the following information from the IOC container in the context:
EAS. Objects. icontainer Container = contexthelper. Context. container;
// Data retrieval connection
Idataconnection dbcn = container. getservicecomponentinstance (typeof (idataconnection) as idataconnection;
// Accessors
Idataaccessor dataaccessor = dataconnection. createdataaccessor ();
We cannot know the specific implementation of UDA objects in advance during programming in different ways, such as agileeas.. NET platform practices the concept of "Backward interface-driven". The specific instance types of UDA objects are written in the configuration file:
<Object name = "masterdataaccessor" assembly = "EAS. Data" type = "EAS. Data. Access. oledbaccessor" lifestyletype = "Singleton">
<Property name = "connection" type = "object" value = "masterdbconnection"/>
</Object>
<Object name = "masterdbconnection" assembly = "EAS. Data" type = "EAS. Data. Access. oledbconnection" lifestyletype = "Singleton">
<Property name = "connectionstring" type = "string" value = "provider = sqloledb.1; persist Security info = false; user id = sa; Password = sa; initial catalog = EAS; data Source = vm2003 "/>
</Object>.
Link
Agileeas. NET platform development guide-series Directories
Introduction to agileeas. NET application development platform-Index
Official website of agileeas. net
Agile Software Engineering Lab
QQ: 116773358