Connection 对象表示数据库连接或类似的资源,它是 .NET
数据提供程序用户的起点。虽然任何具有类似行为的实体都可以公开为
IDbConnection,但该对象主要表示与数据库服务器的连接。
在您的实现中,必须确保先创建和打开 Connection,然后才可以执行
Command。请确保您的实现要求客户端显式打开和关闭连接,而不是让实现为客户端隐式打开和关闭连接。在获取连接时应执行安全检查;如果为
.NET
数据提供程序中的其他类请求现有连接,则将确保每次使用数据源时都会执行安全检查。
所需连接的属性将表示为连接字符串。强烈建议 .NET
数据提供程序使用 OLE DB 所定义的常见名称/值对系统来支持 ConnectionString
属性。只要可能,提供程序就应该使用与 SQL Server 和 OLE DB
.NET
数据提供程序所使用的相同名称来引用连接属性。这有助于确保多个提供程序之间的一致性。有关更多信息,请参阅位于
http://msdn.microsoft.com/library 的 MSDN 库中的
SqlConnection.ConnectionString 属性
和“OLE DB 编程指南”。
获取 Connection
对象的成本通常很昂贵,因此最好考虑使用池连接或其他技术来减轻此项费用。
IDbConnection
的实现至少应包含两个构造函数:一个默认的构造函数和一个采用连接字符串的构造函数。
以下主题包含 Connection 对象的实现的示例代码。
对于示例 Visual Basic 实现:
- TemplateConnection.vb(略)
- TemplateTransaction.vb(略)
对于示例 C# 实现:
- TemplateConnection.cs
|
using System;
using System.Data;
namespace DotNetDataProviderTemplate
{
public class TemplateConnection : IDbConnection
{
private ConnectionState m_state;
private string
m_sConnString;
// Use the "SampleDb" class to simulate a
database connection.
SampleDb m_sampleDb;
// Always have a default constructor.
public TemplateConnection()
{
// Initialize the connection object
into the closed state.
m_state = ConnectionState.Closed;
/*
* Obtain a connection to the
database. In this case,
* use the SampleDb class to
simulate a connection to
* a real database.
*/
m_sampleDb = new SampleDb();
}
// Have a constructor that takes a connection
string.
public TemplateConnection(string sConnString)
{
// Initialize the connection object
into a closed state.
m_state = ConnectionState.Closed;
}
/****
* IMPLEMENT THE REQUIRED PROPERTIES.
****/
public string ConnectionString
{
get
{
// Always return exactly
what the user set.
// Security-sensitive
information may be removed.
return m_sConnString;
}
set
{
m_sConnString = value;
}
}
public int ConnectionTimeout
{
get
{
// Returns the connection
time-out value set in the connection
// string. Zero indicates
an indefinite time-out period.
return 0;
}
}
public string Database
{
get
{
// Returns an initial
database as set in the connection string.
// An empty string
indicates not set - do not return a null reference.
return "";
}
}
public ConnectionState State
{
get { return m_state; }
}
/****
* IMPLEMENT THE REQUIRED METHODS.
****/
public IDbTransaction BeginTransaction()
{
throw new NotSupportedException();
}
public IDbTransaction
BeginTransaction(IsolationLevel level)
{
throw new NotSupportedException();
}
public void ChangeDatabase(string dbName)
{
/*
* Change the database setting on
the back-end. Note that it is a method
* and not a property because the
operation requires an expensive
* round trip.
*/
}
public void Open()
{
/*
* Open the database connection
and set the ConnectionState
* property. If the underlying
connection to the server is
* expensive to obtain, the
implementation should provide
* implicit pooling of that
connection.
*
* If the provider also supports
automatic enlistment in
* distributed transactions, it
should enlist during Open().
*/
m_state = ConnectionState.Open;
}
public void Close()
{
/*
* Close the database connection
and set the ConnectionState
* property. If the underlying
connection to the server is
* being pooled, Close() will
release it back to the pool.
*/
m_state = ConnectionState.Closed;
}
public IDbCommand CreateCommand()
{
// Return a new instance of a command
object.
return new TemplateCommand();
}
/*
* Implementation specific properties /
methods.
*/
internal SampleDb SampleDb
{
get { return m_sampleDb; }
}
}
}
|
- TemplateTransaction.cs
|
using System;
using System.Data;
namespace DotNetDataProviderTemplate
{
public class TemplateTransaction : IDbTransaction
{
public IsolationLevel IsolationLevel
{
/*
* Should return the current
transaction isolation
* level. For the template, assume
the default
* which is ReadCommitted.
*/
get { return
IsolationLevel.ReadCommitted; }
}
public void Commit()
{
/*
* Implement Commit here. Although
the template does
* not provide an implementation,
it should never be
* a no-op because data corruption
could result.
*/
}
public void Rollback()
{
/*
* Implement Rollback here.
Although the template does
* not provide an implementation,
it should never be
* a no-op because data corruption
could result.
*/
}
}
}
|