.NET Data Provider 编程指南

.NET Data Provider是.NET Framework编程环境下的数据库用户访问数据库的编程接口,用于连接到数据库、执行命令和检索结果。在数据源和代码之间创建了一个最小层,以便在不以功能为代价的前提下提高性能。

5.1 数据类型

.NET Framework在System.Data.DbType中定义了.NET Framework数据提供程序的字段、属性或 Parameter对象的数据类型。DmProvider数据类型就是Dm.DmDbType中定义的数据类型。

表5.1 DmProvider数据类型和.NET Framework数据类型的对应关系
DbType类型 DmProvider类型 DbType类型 DmProvider类型
AnsiString VarChar Int32 Int32
AnsiStringFixedLength VarChar Int64 Int64
Binary Binary Object Blob
Boolean Bit SByte SByte
Byte Byte Single Float
Currency Decimal String VarChar
Date Date StringFixedLength Char
DateTime DateTime Time Time
Decimal Decimal UInt16 UInt16
Double Double UInt32 UInt32
Guid VarChar UInt64 UInt64
Int16 Int16 VarNumeric XDEC
表5.2 DM建表语句支持类型与.NET Framework中类型的对应关系
DM建表语句类型 .NET中对应的类型 DM建表语句类型 .NET中对应的类型
CHAR typeof(String) DOUBLE typeof(Double)
VARCHAR typeof(String) BLOB typeof(Byte[])
BIT typeof(Boolean) DATE typeof(DateTime)
TINYINT typeof(SByte) TIME typeof(DateTime)
SMALLINT typeof(Int16) TIMESTAMP typeof(DateTime)
INT typeof(Int32) BINARY typeof(Byte[])
BIGINT typeof(Int64) VARBINARY typeof(Byte[])
DEC typeof(Decimal) CLOB typeof(String)
REAL typeof(Single) INTERVAL typeof(Object)

5.2 提供的对象和接口

DM .NET Provider接口主要实现了DmConnection、DmCommand、DmDataAdapter、DmDataReader、DmParameter、DmParameterCollection、DmTransaction、DmCommandBuilder、DmConnectionStringBuilder、DmClob和DmBlob共11个对象。

5.2.1 DmConnection对象

DmConnection对象表示一个DM数据库打开的连接。

公共属性

ConnectionString:获取或设置用于连接DM数据库的字符串;

ConnectionTimeout:获取在尝试建立连接时终止尝试并生成错误之前所等待的时间;

Database:DM8不再有database的概念,该属性将不再起任何作用;

DataSource:获取要连接的DM实例的名称;

ServerVersion:DM不支持该属性;

State:获取连接的当前状态;

MppType:MPP连接属性,有效值为DmMppType.LOGIN_MPP_LOCAL、DmMppType.LOGIN_MPP_GLOBAL;

RW_Separate:是否读写分离,有效值为true或false;

RW_Percent:表示分发到主库的事务占主备库总事务的百分比,有效值范围:0~100,默认值为25;

StmtPooling:是否启用句柄重用,有效值为true或fasle;

PoolSize:句柄重用缓冲区的大小。

公共方法

DmConnection():构造函数,初始化DmConnection的新实例;

DmConnection(string connectionString):构造函数,以指定的连接串进行连接对象新实例的初始化;

BeginTransaction():开始数据库事务;

BeginTransaction(IsolationLevel il):以指定的隔离级别启动数据库事务;

ChangeDatabase():DM8不支持该操作,调用该函数将不产生任何影响;

Close():关闭与数据库的连接;

CreateCommand():创建并返回一个与DM关联的DmCommand对象;

GetSchema():返回DM的数据源的全部元信息;

GetSchema(String) :使用指定字符串的元信息名称返回DM元信息结果集;

GetSchema(String, String[]):使用指定字符串的元信息名以及表示限制值的指定字符串数组返回DM元信息结果集;

Open():使用ConnectionString)所指定的属性设置打开数据库连接。

连接串

公共属性ConnectionString是用于连接DM数据库的字符串,其格式为:

<属性名>=<属性值>{;<属性名>=<属性值>}

其中支持的属性名及其意义如下表所示:

属性名 意义
server 服务名。
login_primary 在主备情况下是否仅登录到主库或备库。0:主库不存在的情况下可连接备库;1:只连接主库;2:只连接备库;3:优先连接备库。默认为0。
port 登录端口号。
user 用户名。
password 用户口令。
timeout 连接超时时间,默认15s。
commandTimeout 命令超时时间,默认30s。
appname 应用名。
trace NONE:不记录TRACE; DEBUG:将TRACE内容打印到控制台; TRACE:将TRACE内容记录到运行路径下的ProviderTrace.txt文件中。
primary_key 需要加双引号的关键字。
switch_time 主备切换的次数,默认为3。
switch_interval 主备切换的时间间隔,默认为200ms。
time_zone 时区,默认为当前时区。
rw_separate 是否读写分离,默认为FALSE。
rw_percent 读写分离百分比,默认为25。
connPooling 是否使用连接缓存池,默认为TRUE,表示开启。
connPoolSize 连接池中最大连接数,默认为100,连接池开启时有效。
connPoolCheck 是否检查连接池中连接的有效性,TRUE表示检查, FALSE表示不检查,默认为FALSE,连接池开启时有效。
stmtPooling 是否启用句柄重用,默认为TRUE。
poolSize 句柄重用缓冲区的大小,默认为100。
encoding 客户端本地编码,支持UTF-8或GB18030。默认为GB18030。
logLevel 日志等级,默认为OFF,高级别同时记录低级别的信息。 OFF:不记录; ERROR:记录错误日志; SQL:记录执行SQL信息; INFO:记录全部执行信息。
logDir 生成日志路径,默认为当前执行程序路径,日志文件名自动生成,格式如: DmProvider_2019_09_05_16_49_20.845.log。
enRsCache 是否打开结果集缓存。默认值false。
rsCacheSize 缓存池大小,单位M。默认值10。
rsRefreshFreq 缓存池中结果集更新的频率阈值,即大于该值时才检查命中的结果集是否需要更新,单位秒。默认值10。
lobMode 结果集中大字段类型数据的缓存方式。值为1表示本地只缓存一部分数据;值为2表示本地缓存全部的数据。默认值1。
batchType 绑定多行参数执行时,值为0表示分多次执行,一次只执行一行参数;值为1表示一次执行多行参数。默认值为1。
batchNotOnCall 执行SQL为存储过程时,是否允许一次执行多行参数。默认值为false。
batchContinueOnError 绑定多行参数执行时,某行参数执行出错后,后续参数是否继续执行。默认值为false。
batchAllowMaxErrors 绑定多行参数执行时允许的错误数最大值。默认值为0。
bufPrefetch Fetch获取的结果集内存大小,单位M。默认值为0。
compatibleMode 兼容模式。值为0表示不开启该功能;值为1表示兼容oracle;值为2表示兼容mysql。默认值为0。
isBdtaRS 消息中结果集是否以Bdta格式。默认值为false。
maxRows 返回的结果集最大行数。默认值为0x7fffffff。
scoketTimeout 网络包读写的超时时间值,单位秒。默认值为0。
addressRemap 服务器网络地址映射表。默认值为空串。值格式:address_remap=192.168.1.24:5236,192.168.1.23:5236 。
userRemap 用户名映射表。默认值为空串。格式同 addressRemap。
epSelector 服务名配置的集群选取起始位置的方式。值为0表示随机选取一个站点为起始位置;值为1表示第一个站点就是起始位置。默认值为0。
loginStatus 设置连接的服务器状态。值为0,表示不开启该功能;值为4表示open状态;值为3表示mount状态;值为5表示suspend状态。默认值为0。
ep_selection 当集群中存在故障节点时是否进行连接优化。值为0表示进行优化,重排连接节点次序,故障节点位置靠后;值为1表示不进行优化。默认值为0。
maxLobDataLenPerMsg 指定单条消息中大字段类型数据的最大长度,单位字节,默认值为32000,最小值为1024(1K),最大值为104857600(100M),超出范围则使用默认值。

5.2.2 DmCommand对象

表示要对DM数据库执行的一个 Transact-SQL 语句或存储过程。

公共属性

CommandText:获取或设置要对数据源执行的 Transact-SQL 语句或存储过程;

CommandTimeout:获取或设置在终止执行命令的尝试并生成错误之前的等待时间;

CommandType:获取或设置一个值,该值指示如何解释CommandText属性;

Connection:获取或设置 DmCommand的此实例使用的 DmConnection;

Parameters:获取DmParameterCollection;

Transaction:获取或设置将在其中执行DmCommand 的 DmTransaction;

UpdatedRowSource:获取或设置命令结果在由DbDataAdapter的Update方法使用时如何应用于DataRow。

公共方法

DmCommand():构造函数,初始化DmCommand的新实例;

Cancel():试图取消DmCommand的执行;

CreateParameter():创建DmParameter对象的新实例;

ExecuteNonQuery():对连接执行Transact-SQL语句并返回受影响的行数;

ExecuteReader():将CommandText发送到Connection并生成一个DmDataReader;

ExecuteReader(CommandBehavior):以指定方式执行CommandText;

ExecuteScalar():执行查询,并返回查询所返回的结果集中第一行的第一列。忽略额外的列或行;

Prepare():在DM的实例上创建命令的一个准备版本。

5.2.3 DmDataAdapter对象

用于填充DataSet和更新DM数据库的一组数据命令和一个数据库连接。

公共属性

DeleteCommand:获取或设置一个 Transact-SQL 语句或存储过程,以从数据集删除记录;

InsertCommand:获取或设置一个 Transact-SQL语句或存储过程,以在数据源中插入新记录;

SelectCommand:获取或设置一个 Transact-SQL语句或存储过程,用于在数据源中选择记录;

UpdateCommand:获取或设置一个 Transact-SQL语句或存储过程,用于更新数据源中的记录;

TableMappings:获取一个集合,它提供源表和DataTable之间的主映射。

公共方法

DmDataAdapter():构造函数,初始化DmDataAdapter的新实例;

Fill():在DataSet中添加或刷新行以匹配数据源中的行;

FillSchema():将DataTable添加到DataSet中,并配置架构以匹配数据源中的架构;

Update():为DataSet中每个已插入、已更新或已删除的行调用相应的INSERT、UPDATE 或 DELETE 语句。

5.2.4 DmDataReader对象

通过只向前方式从结果集中获取行数据。

公共属性

Depth:获取一个值,该值指示当前行的嵌套深度,目前DM返回常数0;

FieldCount:获取当前行中的列数;

IsClosed:获取一个值,该值指示数据读取器是否已关闭;

RecordsAffected:获取执行Transact-SQL语句所更改、插入或删除的行数。

公共方法

Close():关闭DmDataReader对象;

GetBoolean():获取指定列的布尔值形式的值;

GetByte():获取指定列的字节形式的值;

GetBytes():从指定的列偏移量将字节流读入缓冲区,并将其作为从给定的缓冲区偏移量开始的数组;

GetChar():获取指定列的单个字符串形式的值;

GetChars():从指定的列偏移量将字符流作为数组从给定的缓冲区偏移量开始读入缓冲区;

GetDataTypeName():获取源数据类型的名称;

GetDateTime():获取指定列的DateTime对象形式的值;

GetDecimal():获取指定列的Decimal对象形式的值;

GetDouble():获取指定列的双精度浮点数形式的值;

GetEnumerator():返回可循环访问集合的枚举数;

GetFieldType():获取是对象的数据类型的Type;

GetFloat():获取指定列的单精度浮点数形式的值;

GetInt16():获取指定列的16位有符号整数形式的值;

GetInt32():获取指定列的32位有符号整数形式的值;

GetInt64():获取指定列的64位有符号整数形式的值;

GetKeyCols():获取构成主关键字的列;

GetName():获取指定列的名称;

GetOrdinal():在给定列名称的情况下获取列序号;

GetSchemaTable():返回一个DataTable,它描述DmDataReader的列元数据;

GetString():获取指定列的字符串形式的值;

GetUniqueCols():获取有唯一性约束的列;

GetValue():获取以本机格式表示的指定列的值;

GetValues():获取当前行的集合中的所有属性列;

IsDBNull():获取一个值,该值指示列中是否包含不存在的或缺少的值;

NextResult():当读取批处理Transact-SQL语句的结果时,使数据读取器前进到下一个结果;

Read():使DmDataReader 前进到下一条记录。

5.2.5 DmParameter对象

表示DmCommand的参数以及这些参数各自到DataSet中的列的映射。

公共属性

DbType:获取或设置参数的DbType;

Direction:获取或设置一个值,该值指示参数是只可输入、只可输出、双向还是存储过程返回值参数;

ParameterName:获取或设置DmParameter的名称;

Precision:获取或设置用来表示Value属性的最大位数;

Scale:获取或设置Value解析为的小数位数;

Size:获取或设置列中数据的最大大小;

SourceColumn:获取或设置源列的名称,该源列映射到DataSet并用于加载或返回Value;

SourceVerion:获取或设置在加载Value时使用的DataRowVersion;

Value:获取或设置该参数的值。

公共方法

DmParameter():构造函数,初始化DmParameter的新实例。

5.2.6 DmParameterCollection对象

表示与DmCommand相关的参数集合以及这些参数各自到DataSet中的列的映射。

公共属性

Count:获取集合中DmParameter对象的数目。

公共方法

Add():将DmParamter添加到 DmParameterCollection;

Clear():从集合中移除所有项;

Contains():获取一个值,该值指示集合中是否存在DmParameter;

CopyTo():将DmParameter对象从DmParameterCollection 复制到指定的数组;

IndexOf():获取DmParameter在集合中的位置;

Insert():将 DmParameter插入到集合中的指定索引位置;

Remove():从集合中移除指定的 DmParameter;

RemoveAt():从集合中移除指定的 DmParameter。

5.2.7 DmTransaction对象

表示要在DM数据库中处理的Transact-SQL事务。

公共属性

Connection:获取与该事务关联的DmConnection对象;

IsolationLevel:指定该事务的 IsolationLevel。

公共方法

Commit():提交数据库事务;

Dispose():释放由DmTransaction占用的非托管资源,还可以释放托管资源;

Rollback():回滚数据库事务;

Save():在事务中创建保存点,并指定保存点名称。

5.2.8 DmCommandBuilder对象

自动生成用于协调DataSet的更改与关联数据库的单表命令。继承自DbCommandBuilder。

公共属性

ConflictOption:指定 ConflictOption选项;

QuotePrefix:获取或设置指定其名称包含空格或保留标记等字符的数据库对象(例如,表或列)时使用的开始字符;

QuoteSuffix:获取或设置一个或多个结束字符,供指定其名称中包含空格或保留标记等字符的数据库对象(例如,表或列)时使用。

公共方法

使用继承自DbCommandBuilder的公共方法。

5.2.9 DmConnectionStringBuilder对象

自动生成用于连接对象进行连接的字符串。 继承自DbCommandBuilder。

公共属性

ConflictOption:指定 ConflictOption选项;

QuotePrefix:获取或设置指定其名称包含空格或保留标记等字符的数据库对象(例如,表或列)时使用的开始字符;

QuoteSuffix:获取或设置一个或多个结束字符,供指定其名称中包含空格或保留标记等字符的数据库对象(例如,表或列)时使用。

公共方法

使用继承自DbCommandBuilder的公共方法。

5.2.10 DmClob对象

用于访问服务器的字符类型的大字段对象。

公共属性

无。

公共方法

String GetString(int pos, int length):从pos所指定的位置获取个数为length字符。pos从1开始计数。如果length超过所取字符,则返回实际长度的字符;

int Length():获取大字段的长度;

int SetString(long pos, String str, int offset, int len):从pos所指定的位置,更新大字段内容为str的内容,offset为设置str的偏移,len为偏移后设置的字符串长度;

void Truncate(long len):截断大字段为len长度;

String GetSubString(long pos, int length):从pos所指定的位置,获取长度为length的字符串。

5.2.11 DmBlob对象

用于访问服务器二进制类型大字段。

公共属性

无。

公共方法

int Length():获取大字段数据长度;

int SetBytes(long pos, byte[] bytes, int offset, int len):从pos所指定的位置,更新大字段内容为bytes的内容,offset为设置bytes的偏移,len为偏移后设置的字节长度;

byte[] GetBytes(long pos, int length):从pos所指定的位置获取length个数的字节数据;

void truncate(long len):将大字段截断为len长度;

Stream GetStream():获取流对象,通过流对象进行数据读取。

5.2.12 DmBulkCopy对象

用于快速批量装载数据。实现IDisposable接口。该功能依赖DM安装目录\bin下的dmfldr_dll.dll等动态链接库,需要拷贝到应用程序的执行目录。

公共属性

DestinationTableName:指定目标表名;

ColumnMappings:指定源数据列与目标表列的映射集合;

BatchSize:指定一次发送的数据行数,默认值为100。

公共方法

void WriteToServer(DataRow[] rows) :装载数据;

void WriteToServer(DataTable table) :装载数据;

void WriteToServer(DataTable table, DataRowState rowState) :装载数据;

void WriteToServer(DmDataReader reader) :装载数据。

5.3 注册.NET驱动

有部分场景,使用DmProvider时需要注册.NET驱动,例如通过DbProviderFactories类调用DmProvider创建连接,NHibernate及EFDmProvider的使用,都需要注册.net驱动。下面详细介绍下如何注册.NET驱动。

步骤如下:

1、注册DmProvider。

gacutil /if E:\dmdbms\drivers\dotNetProvider\DmProvider\DmProvider.dll

2、修改对应框架的配置文件machine.config。

例如,配置文件machine.config目录位于C:\Program Files\Microsoft Visual Studio10.0\VC>notepad%WINDIR%\Microsoft.NET\Framework\v2.0.50727\config\machine.config。在配置文件machine.config中添加以下内容:

...
<DbProviderFactories>
            <add description="DM .Net Framework Data Provider" invariant="Dm" name="DM Data Provider" type="Dm.DmClientFactory, DmProvider, Version=1.1.0.0, Culture=neutral, PublicKeyToken=7a2d44aa446c6d01"/>
</DbProviderFactories>
...

例如,通过DbProviderFactories类调用DmProvider创建连接使用.NET驱动的情况。

using System.Data.Common;
...
 public static void TestFunc()
        {
            DbProviderFactory factory = DbProviderFactories.GetFactory("Dm");
            DbConnection sconn = factory.CreateConnection();
            sconn.ConnectionString = "Server=localhost; UserId=SYSDBA; PWD=SYSDBA";
            sconn.Open();
            DbCommand scmd = factory.CreateCommand();
            scmd.Connection = sconn;
            try
            {
                scmd.CommandText = "drop table t1 cascade;";
                scmd.ExecuteNonQuery();
            }
            catch (Exception)
            {   
            }
}

5.4 Nhibernate Dm方言包

DmDialect.dll是基于Dm数据库开发的支持Nhibernate的方言包类库,放在DM安装目录..\drivers\dotNetProvider\DmDialect中,方言包程序集名为:DmDialect,Version=1.0.0.0, Culture=neutral, PublicKeyToken=072d25982b139bf8。

Nhibernate Dm方言包支持NET Framework,NET Core, NET Standard框架平台,与Nhibernate的版本是保持一致的。

DmDialect.dll中包含的类有:NHibernate.Driver.DmDriver、NHibernate.Dialect.DmDialect、Nhibernate.Dialect.Schema.DmDataBaseSchema、NHibernate.AdoNet.DmBatchingBatcher和NHibernate.AdoNet. DmBatchingBatcherFactory。

下面介绍一下如何使用方言包:

1.添加方言包依赖项。

Nhibernate Dm方言包依赖项为:DmProvider.dll和Nhibernate.dll。

2.应用程序添加依赖项之后,修改Nhibernate配置属性。

"dialect": NHibernate.Dialect.DmDialect, DmDialect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=072d25982b139bf8
"connection.driver_class": NHibernate.Driver.DmDriver, DmDialect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=072d25982b139bf8
"connection.connection_string": Server=localhost;UserId=SYSDBA;PWD=SYSDBA;encoding=utf-8;PORT=5236

5.5 EFDmProvider.EF6方言包

DM基于DmProvider数据库驱动提供了方言包程序EFDmProvider.EF6以支持微软的EF6(EntityFrameWork)框架。应用程序使用EF6连接到DM数据库时,不仅需要DmProvider.dll和EFDmProvider.EF6.dll,同时配置文件(默认文件名是App.config)需满足如下格式:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
	<!--EF6配置类-->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
	<!--EFDmProvider.EF6配置类,提供一些兼容性配置。若无相关需求则可以注释-->
	<section name="EFDm" type="EFDmProvider.config.EFDmConfigurationSection, EFDmProvider.EF6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=514fc861b4bfc6c6" requirePermission="false" />
   </configSections>

<!--DmProvider注册,参考驱动注册章节-->
  <system.data>
    <DbProviderFactories>
      <remove invariant="Dm"></remove>
      <add description="DM .Net Framework Data Provider" invariant="Dm" name="DM Data Provider" type="Dm.DmClientFactory, DmProvider, Version=1.1.0.0, Culture=neutral, PublicKeyToken=7a2d44aa446c6d01"/>
    </DbProviderFactories>
  </system.data>

 <!--EF6配置项-->
   <entityFramework>
    <providers>
	<!--- EFDmProvider.EF6提供支持->
      <provider invariantName="Dm" type="EFDmProvider.DmProviderServices, EFDmProvider.EF6" /> 
    </providers>
  </entityFramework>
 
	<!--EFDmProvider.EF6配置项,若无相关需求,则可以注释-->
<EFDm>
		<!-- varcharMaxToClob标签属性value 为true 表示SqlServer varcharMax类型映射到DM的Clob类型; value为false表示映射到DM的varchar类型。 默认为true->
    <varcharMaxToClob value = "true"/>
  </EFDm>

<!--- 连接串配置-->
  <connectionStrings>
    <add name="VOMEntities"  providerName="Dm" connectionString="Server=LOCALHOST;User=USER1;password=USER1;PORT=5236"/>

  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

5.6 DM-EFCore方言包

5.6.1 介绍

EFCore.Dm程序包是DM数据库提供的基于EFCore框架连接到DM数据库的方言包程序。

5.6.2 使用

EFCore.Dm方言包位于安装目录..\drivers\dotNet\EFCore.Dm路径,该程序包依赖DmProvider程序和EFCore程序,依赖信息在EFCore.Dm路径下的Microsoft.EntityFrameworkCore.Dm.2.1.1.nuspec文件中可以看到,使用时直接将EFCore.Dm程序包及其依赖程序包添加到nuget程序包源后,然后在应用程序中添加nuget依赖即可。

5.6.3 示例

执行该示例前需要在数据库建表:

create table "Customers"("Id" varchar);
public class CustomerContext : DbContext
    {
        public CustomerContext(DbContextOptions options):base(options)
        {
        }
        public DbSet<Customer> Customers { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Customer>(b =>
            {
                b.HasKey(c => c.Id);
                b.ToTable("Customers");
            });
        }
    }
    public class Customer
    {
        public string Id { get; set; }
    }
classProgram
    {
staticvoid Main(string[] args)
        {
try
            {
var options = newDbContextOptionsBuilder()
                    .UseDm("SERVER=localhost;PORT=5236;USER=SYSDBA;PASSWORD=SYSDBA")
                    .UseInternalServiceProvider(
newServiceCollection()
                            .AddEntityFrameworkDm()
                            .BuildServiceProvider())
                    .Options;
using (var context = newCustomerContext(options))
                {
context.Database.EnsureCreated();
var cus1 = new Customer { Id = "abc"};
var cus2 = new Customer { Id = "qqq" };
context.Customers.AddRange(cus1, cus2);
context.SaveChanges();
var results = context.Customers.Where(c =>c.Id.StartsWith("a"))
                        .OrderByDescending(c =>c.Id)
                        .ToList();
Console.WriteLine(results[0].Id);
                }
            }
catch (Exception e)
            {
Console.WriteLine("异常:" + e.Message);
            }
Console.WriteLine("test over");
        }
    }

5.7 NET Data Provider基本示例

下面的示例使用DM .NET Data Provider,实现DM数据库的连接与查询,代码使用C##编写:

首先在项目中引用DmProvider.dll,DmProvider.dll在达梦数据库安装目录下的bin文件夹下可以找到。

using System;
using System.Collections.Generic;
using System.Text;
using Dm;
namespace DMDemo
{
    class Demo
    {
        //返回结果
		static int ret = 1;
		static DmConnection cnn = new DmConnection();
		[STAThread]
		static int Main(string[] args)
		{
			try
			{
				cnn.ConnectionString = "Server=localhost; User Id=SYSDBA; PWD=SYSDBA";
				cnn.Open();
                Demo demo = new Demo();
                demo.TestFunc();
				cnn.Close();
			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
            Console.ReadLine();
			return ret;
		}
		public void TestFunc()
		{
			DmCommand command = new DmCommand();
            command.Connection = cnn;
			try
			{
                string a, b, c;
                command.CommandText = "SELECT NAME, AUTHOR, PUBLISHER FROM PRODUCTION.PRODUCT;";
				DmDataReader reader =(DmDataReader)command.ExecuteReader();
				while(reader.Read())
				{
                    a = reader.GetString(0);
				 b = reader.GetString(1);
                    c = reader.GetString(2);
                    Console.WriteLine("NAME:" + a);
                    Console.WriteLine("AUTHOR:" + b);
                    Console.WriteLine("PUBLISHER:" + c);
                    Console.WriteLine("-------------------");
				}
			}
			catch(Exception ex)
			{
                Console.WriteLine(ex.Message);
				ret = 0;
			}
		}
    }
}

5.8 对象使用

5.8.1 连接

DM .NET Provider使用DMConnection对象提供与DM数据库的连接。DM .NET
Provider支持连接字符串格式。

例如指定与本机的DM数据库建立连接,用户名和口令均为“SYSDBA”,则代码片断如下。

DmConnection conn = new DmConnection("Server=localhost; User Id=SYSDBA;PWD=SYSDBA");
conn.Open();

5.8.2 查询与结果集

当建立与数据库的连接后,可以使用DmCommand对象来执行命令并从数据库中返回结果。您可以使用DmCommand构造函数来创建命令,该构造函数采用在数据源、DmConnection对象和DmTransaction对象中执行的SQL语句的可选参数。也可以使用DmConnection的CreateCommand()方法来创建用于特定DmConnection对象的命令。您可以使用DmCommandText属性来查询和修改DmCommand对象的SQL语句。

DmCommand 对象公开了几个可用于执行所需操作的 Execute方法。当以数据流的形式返回结果时,使用 ExecuteReader() 可返回 DataReader
对象。使用 ExecuteScalar() 可返回单个值。使用 ExecuteNonQuery()可执行不返回行的命令。

可以使用 DmDataReader从数据库中检索只读、只进的数据流。查询结果在查询执行时返回,并存储在客户端的缓冲区中,直到您使用DmDataReader的Read()方法对它们发出请求。

当创建DmCommand对象的实例后,可调用DmCommand.ExecuteReader()从数据源中检索行,从而创建一个DmDataReader,如以下程序片断所示:

var command = conn.CreateCommand();
command.CommandText = "SELECT NAME, AUTHOR, PUBLISHER FROM 
PRODUCTION.PRODUCT;";
var myReader = command.ExecuteReader();

5.8.3 插入、更新、删除

通过DmCommand对象的ExecuteNonQuery方法可以执行INSERT语句来插入数据,C##示例代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using Dm;
namespace DMDemo
{
    class InsertDemo
    {
        //返回结果
        static int ret = 1;
        static DmConnection cnn = new DmConnection();
        [STAThread]
        static int Main(string[] args)
        {
            try
            {
                cnn.ConnectionString = "Server=localhost; User Id=SYSDBA; PWD=SYSDBA";
                cnn.Open();
                InsertDemo demo = new InsertDemo();
                demo.TestFunc();
                cnn.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
            return ret;
        }
        public void TestFunc()
        {
            var command = cnn.CreateCommand();  
            try
            {
                command.CommandText = "INSERT INTO PRODUCTION.PRODUCT(NAME, AUTHOR, PUBLISHER, " +
                 "PUBLISHTIME, PRODUCT_SUBCATEGORYID, PRODUCTNO, SATETYSTOCKLEVEL, ORIGINALPRICE, " +
                 "NOWPRICE, DISCOUNT, DESCRIPTION, TYPE, PAPERTOTAL, WORDTOTAL, SELLSTARTTIME, " +
           "SELLENDTIME) VALUES ('三国演义', '罗贯中', '中华书局', '2005-04-01', 4, '9787101046121', " +
          "10, 19.0000, 15.2000, 8.0, '《三国演义》是中国第一部长篇章回体小说,中国小说" +
         "由短篇发展至长篇的原因与说书有关。宋代讲故事的风气盛行,说书成为一种职业,说" +
         "书人喜欢拿古代人物的故事作为题材来敷演,而陈寿《三国志》里面的人物众多,事件" +
         "纷繁,正是撰写故事的最好素材。三国故事某些零星片段原来在民间也已流传,加上说" +
         "书人长期取材,内容越来越丰富,人物形象越来越饱满,最后由许多独立的故事逐渐组" +
         "合而成长篇巨著。这些各自孤立的故事在社会上经过漫长时间口耳相传,最后得以加工" +
         "、集合成书,成为中国第一部长篇章回体小说,这是一种了不起的集体创造,与由单一" +
           "作者撰写完成的小说在形态上有所不同。', '16', 943, 93000, '2006-03-20', '1900-01-01')";
                command.ExecuteNonQuery();
                string a, b, c;
                command.CommandText = "SELECT NAME, AUTHOR, PUBLISHER FROM PRODUCTION.PRODUCT;";
                var reader = command.ExecuteReader();
                while (reader.Read())
                {
                    a = reader.GetString(0);
                    b = reader.GetString(1);
                    c = reader.GetString(2);
                    Console.WriteLine("NAME:" + a);
                    Console.WriteLine("AUTHOR:" + b);
                    Console.WriteLine("PUBLISHER:" + c);
                    Console.WriteLine("-------------------");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = 0;
            }
        }
    }
}

通过DmCommand对象的ExecuteNonQuery方法可以执行UPDATE语句来更新数据,C##示例代码如下:

command.CommandText = "UPDATE PRODUCTION.PRODUCT SET "
	+ " NAME = '三国演义(上)' WHERE PRODUCTID = 11";
command.ExecuteNonQuery();

通过DmCommand对象的ExecuteNonQuery方法可以执行DELETE语句来删除数据,C##示例代码如下:

command.CommandText = "DELETE FROM PRODUCTION.PRODUCT WHERE PRODUCTID = 11";
command.ExecuteNonQuery();

5.8.4 大对象

下面的示例将展示读取一张图片到并保存到数据库中。图片以二进制数据存储在PRODUCT表中的PHOTO字段中。

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Dm;
namespace DMDemo
{
    class BinaryDemo
    {
        //返回结果
        static int ret = 1;
        static DmConnection cnn = new DmConnection();
        [STAThread]
        static int Main(string[] args)
        {
            try
            {
                cnn.ConnectionString = "Server=localhost; User Id=SYSDBA; PWD=SYSDBA";
                cnn.Open();
                BinaryDemo demo = new BinaryDemo();
                demo.TestFunc();
                cnn.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
            return ret;
        }
        public void TestFunc()
        {
            DmCommand command = new DmCommand();
            command.Connection = cnn;
            try
            {
                FileInfo fi = new FileInfo(@"F:\dotnet\dameng\DM数据库例子\三国演义.jpg");
                FileStream fs = fi.OpenRead();
                int nBytes = (int)fs.Length;
                byte[] dataArray = new byte[nBytes];
                fs.Read(dataArray, 0, nBytes);
                fs.Close();
                command.CommandText = "UPDATE  PRODUCTION.PRODUCT SET PHOTO = :PHOTO WHERE PRODUCTID = 11";
                DmParameter param1 = new DmParameter(":PHOTO", DmDbType.Binary);
                command.Parameters.Add(param1);
                param1.Value = dataArray;
                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = 0;
            }
        }
    }
}

5.8.5 自增列

达梦数据库.NET Data Provider接口支持自增列,如果数据库中的列设置为自增,那么在往数据库中插入记录的时候,不需要给该字段赋值。例如PRODUCT表中的PRODUCTID字段就设置为自增了,在插入数据时没有给PRODUCTID字段赋值,在数据插入达梦数据库时,由数据库根据PRODUCTID自增列的设置自动进行赋值。

5.8.6 存储过程与函数

达梦数据库.NET Data Provider可以使用DmCommand对象来执行存储过程与函数。

创建一个存储过程“UPDATEPRODUCT”用来更新表PRODUCT中的NAME字段,存储过程代码如下:

CREATE OR REPLACE PROCEDURE "PRODUCTION"."UPDATEPRODUCT"
(
  V_ID INT,
  V_NAME VARCHAR(50)
)
AS
BEGIN
  UPDATE PRODUCTION.PRODUCT SET NAME = V_NAME WHERE PRODUCTID = V_ID;
END;

达梦数据库.NET Data Provider调用存储过程的示例代码如下:

using Dm;
namespace DMDemo
{
    class ProcDemo
    {
        //返回结果
        static int ret = 1;
        static DmConnection cnn = new DmConnection();
        [STAThread]
        static int Main(string[] args)
        {
            try
            {
                cnn.ConnectionString = "Server=localhost; User Id=SYSDBA; PWD=SYSDBA";
                cnn.Open();
                ProcDemo demo = new ProcDemo();
                demo.TestFunc();
                cnn.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
            return ret;
        }
        public void TestFunc()
        {
            var command = cnn.CreateCommand();
            try
            {
                command.CommandText = "PRODUCTION.UPDATEPRODUCT";
                command.CommandType = System.Data.CommandType.StoredProcedure;
                DmParameter parm1 = new DmParameter(":V_ID", DmDbType.Int32);
                command.Parameters.Add(parm1);
                parm1.Value = 1;
                parm1.Direction = System.Data.ParameterDirection.Input;
                DmParameter parm2 = new DmParameter(":V_NAME", DmDbType.VarChar);
                command.Parameters.Add(parm2);
                parm2.Value = "红楼梦(下)";
                parm2.Direction = System.Data.ParameterDirection.Input;
                command.ExecuteNonQuery();
                string a, b, c;
                command.Parameters.Clear();
                command.CommandText = "SELECT NAME, AUTHOR, PUBLISHER FROM PRODUCTION.PRODUCT;";
                var reader = command.ExecuteReader();
                while (reader.Read())
                {
                    a = reader.GetString(0);
                    b = reader.GetString(1);
                    c = reader.GetString(2);
                    Console.WriteLine("NAME:" + a);
                    Console.WriteLine("AUTHOR:" + b);
                    Console.WriteLine("PUBLISHER:" + c);
                    Console.WriteLine("-------------------");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = 0;
            }
        }
    }
}

以上代码调用存储过程“UPDATEPRODUCT”将PRODUCT表中的PRODUCTID字段内容为1的记录的NAME字段内容由"红楼梦"更新为"红楼梦(下)"。

微信扫码
分享文档
扫一扫
联系客服