俺以前一直是弱类型DataSet的拥护者。因为它实在是太方便了,性能,多表操作上的表现都无可挑剔。
但是它在Remoting序列化的时候,如果是深层的多表关联,会导致数据量的急剧膨胀(.Net 1.1环境)
所以开始考虑用.Net 2.0来实现customer object
试了两天,发现新的.Net带来的泛型,为customer object的设计带来了显著的便利
举个例子,先设计一个customer object ,BillHeader
public BillHeader(DataRow dr)

{
BillHeaderUuid = (string)dr["BillHeaderUuid"];
BlNo = (string)dr["BlNo"];
Pol = (string)dr["Pol"];
Pod = (string)dr["Pod"];
}

public DataRow ToDataRow(DataRow dr)

{
dr["BillHeaderUuid"] = BillHeaderUuid;
dr["BlNo"] = BlNo;
dr["Pol"] = Pol;
dr["Pod"] = Pod;
return dr;
}
接下来是collections,
public partial class BillHeaders : List<BillHeader>

{

private DataTable _Table;

public DataTable Table

{
get

{
if (_Table == null)

{
InitTable();
}
foreach (BillHeader bh in this)

{
_Table.Rows.Add(bh.ToDataRow(_Table.NewRow()));
}
return _Table;
}
set

{
foreach (DataRow dr in value.Rows)

{
this.Add(new BillHeader(dr));
}
_Table = value;
}
}

public void InitTable()

{
_Table = new DataTable();
_Table.TableName = "BillHeader";
_Table.Columns.Add("BlNo", typeof(string));
_Table.Columns.Add("Pol", typeof(string));
_Table.Columns.Add("Pod", typeof(string));

}
}
在界面层的调用方法
BillHeaders bhs = new BillHeaders();
BindingSource bs = new BindingSource();


private void LoadForm()

{
this.bs.DataSource = bhs;
this.bn.BindingSource = bs;
this.blNoTextBox.DataBindings.Add(new Binding("Text", this.bs, "blNo", true));
this.polTextBox.DataBindings.Add(new Binding("Text", this.bs, "pol", true));
this.podTextBox.DataBindings.Add(new Binding("Text", this.bs, "pod", true));

}
这里只用到了泛型的基本特性,但已经可以感受到它带来的威力
正在进一步学习中。。。
在应用.Net 2.0 连接Oracle的时候遇到了问题:
1.1时代都是直接Using System.Data.OracleClient,.Net 2.0改进成使用DBProvider(System.Data.Common)的方式,
看起来很美,但是用到Oracle存储过程返回结果集的时候愣住了
DBType没有支持Cursor的类型?!查了资料半天也没有结果
如果实在没办法只好回到System.Data.OracleClient了
.NET Framework Data Provider for Oracle
| Oracle type |
.NET Framework type |
.NET Framework typed accessor |
OracleType typed accessor |
|
BFILE |
Byte[] |
GetBytes() |
GetOracleBFile() |
|
BLOB |
Byte[] |
GetBytes() |
GetOracleLob() |
|
CHAR |
String
Char[] |
GetString()
GetChars() |
GetOracleString() |
|
CLOB |
String
Char[] |
GetString()
GetChars() |
GetOracleLob() |
|
DATE |
DateTime |
GetDateTime() |
GetOracleDateTime() |
|
FLOAT |
Decimal |
GetDecimal() |
GetOracleNumber() ** |
|
INTEGER |
Decimal |
GetDecimal() |
GetOracleNumber() ** |
|
INTERVAL YEAR TO MONTH * |
Int32 |
GetInt32() |
GetOracleMonthSpan() |
|
INTERVAL DAY TO SECOND * |
TimeSpan |
GetTimeSpan() |
GetOracleTimeSpan() |
|
LONG |
String
Char[] |
GetString()
GetChars() |
GetOracleString() |
|
LONG RAW |
Byte[] |
GetBytes() |
GetOracleBinary() |
|
NCHAR |
String
Char[] |
GetString()
GetChars() |
GetOracleString() |
|
NCLOB |
String
Char[] |
GetString()
GetChars() |
GetOracleLob() |
|
NUMBER |
Decimal |
GetDecimal() |
GetOracleNumber() ** |
|
NVARCHAR2 |
String
Char[] |
GetString()
GetChars() |
GetOracleString() |
|
RAW |
Byte[] |
GetBytes() |
GetOracleBinary() |
|
REF CURSOR |
|
|
|
|
ROWID |
String
Char[] |
GetString()
GetChars() |
GetOracleString() |
|
TIMESTAMP * |
DateTime |
GetDateTime() |
GetOracleDateTime() |
|
TIMESTAMP WITH LOCAL TIME ZONE * |
DateTime |
GetDateTime() |
GetOracleDateTime() |
|
TIMESTAMP WITH TIME ZONE * |
DateTime |
GetDateTime() |
GetOracleDateTime() |
|
UNSIGNED INTEGER |
Decimal |
GetDecimal() |
GetOracleNumber() ** |
|
VARCHAR2 |
String
Char[] |
GetString()
GetChars() |
GetOracleString() |
问题最终用一下的方式解决:
DbParameter param = dpfProvider.CreateParameter();
if (sourceColumn == ORACLE_REF_CURSOR)
{
OracleParameter op = new OracleParameter();
op.OracleType = OracleType.Cursor;
param = op;
}
虽然看起来有点不伦不类,但是能运行,而且支持多个Oracle Ref Cursor
目前开始了一个新的项目,经过不长时间的斟酌,打算用VS 2005开发
项目是12月初开始的,预计6月底完成
这算作自己的第一篇文章,留作纪念