C# C:映射IDataReader.GetTableSchema()和DbType枚举?
因此,我有以下内容:从MyTable中选择* 当我执行以下操作时,我将返回TableData,这很有用,但仍然会留下一些未知的内容C# C:映射IDataReader.GetTableSchema()和DbType枚举?,c#,database,database-schema,query-parameters,dbtype,C#,Database,Database Schema,Query Parameters,Dbtype,因此,我有以下内容:从MyTable中选择* 当我执行以下操作时,我将返回TableData,这很有用,但仍然会留下一些未知的内容 //CommandBehavior.KeyInfo seems to actually return the correct primary keys // not so much with CommandBehavior.SchemaOnly. IDataReader reader = command.ExecuteReader(CommandBehavior.K
//CommandBehavior.KeyInfo seems to actually return the correct primary keys
// not so much with CommandBehavior.SchemaOnly.
IDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo)
DataTable table = reader.GetSchemaTable();
现在,在迭代我的表时,我遇到一个名为DataType的列,它是System.String或System.Byte[]或System.Int32,等等。但是,这只告诉我要存储的.NET类型,而没有告诉我System.Decimal是DbType.Currency还是DbType.Decimal。因此,当我创建IDataParameter时,我不确定要为DbType设置什么
parameter.ColumnName = columnName;
parameter.DbType = DbType.Decimal; (or should it have been Currency?)
基本上,我如何才能得到表的真实模式。。。或者这有关系吗?如果要为存储过程或某些sql文本传递参数,则不需要指定参数数据类型。SqlCommand将为您正确分配数据类型 我相信,如果您想覆盖系统将为您选择的内容,则可以在参数上指定DBType 使用
SqlCommand.Parameters.AddWithValue("@parameterName", valueAsObject);
命令
编辑您使用的是IDB命令,而不是SqlCommand。我知道SqlCommand和Oracle命令都不需要您指定DbType,但我不知道其他框架是否需要您显式设置DbType。以下是将system.type转换为DbType枚举值的方法:
Class DBTypeConversion
{
private static String[,] DBTypeConversionKey = new String[,]
{
{"BigInt","System.Int64"},
{"Binary","System.Byte[]"},
{"Bit","System.Boolean"},
{"Char","System.String"},
{"DateTime","System.DateTime"},
{"Decimal","System.Decimal"},
{"Float","System.Double"},
{"Image","System.Byte[]"},
{"Int","System.Int32"},
{"Money","System.Decimal"},
{"NChar","System.String"},
{"NText","System.String"},
{"NVarChar","System.String"},
{"Real","System.Single"},
{"SmallDateTime","System.DateTime"},
{"SmallInt","System.Int16"},
{"SmallMoney","System.Decimal"},
{"Text","System.String"},
{"Timestamp","System.DateTime"},
{"TinyInt","System.Byte"},
{"UniqueIdentifer","System.Guid"},
{"VarBinary","System.Byte[]"},
{"VarChar","System.String"},
{"Variant","System.Object"}
};
public static SqlDbType SystemTypeToDbType( System.Type sourceType )
{
SqlDbType result;
String SystemType = sourceType.ToString();
String DBType = String.Empty;
int keyCount = DBTypeConversionKey.GetLength(0);
for(int i=0;i<keyCount;i++)
{
if(DBTypeConversionKey[i,1].Equals(SystemType)) DBType = DBTypeConversionKey[i,0];
}
if (DBType==String.Empty) DBType = "Variant";
result = (SqlDbType)Enum.Parse(typeof(SqlDbType), DBType);
return result;
}
public static Type DbTypeToSystemType( SqlDbType sourceType )
{
Type result;
String SystemType = String.Empty;
String DBType = sourceType.ToString();
int keyCount = DBTypeConversionKey.GetLength(0);
for(int i=0;i<keyCount;i++)
{
if(DBTypeConversionKey[i,0].Equals(DBType)) SystemType = DBTypeConversionKey[i,1];
}
if (SystemType==String.Empty) SystemType = "System.Object";
result = Type.GetType(SystemType);
return result;
}
希望这有助于更好地澄清
遗憾的是,如果您使用IDB命令,就不能在一行中完成。您不能执行类似command.Parameters.Addparam.Value=thevalue的操作
此外,您不需要设置参数的DbType。正确的映射是自动为您完成的:我没有使用SqlCommand。我的类型是IDbCommand类型。在IDbCommand中,不能执行command.Parameters.AddWithValue。。。;仅限command.Parameters.Add,因为command.Parameters的类型IDataParameterCollection.NB在某种程度上是正确的。您不需要显式地设置DbType,只需传入值即可。然而,你也是对的。IDbCommand.Parameters没有AddWithValue方法。看看下面我的答案…我的错!接口没有指定这种区别。我知道SqlCommand和OracleCommand对象都不需要定义DbType。但是我不知道还有其他可能需要它们的实现。我已经用相应的方法更新了我的答案。@NB:整个转换器映射问题解决不了任何问题,因为我仍然想知道是否应该将System.Decimal映射到DbType.Decimal或DbType.Currency。但是,你是对的。我将让驱动程序决定将我的系统.Decimal映射到什么。啊,是的,Decimal数据类型非常混乱,因为SQL Server中的Decimal定义了一个精度范围,即周期前后的位数,与.net Decimal相比,精度可变的Decimal要灵活得多。我将编写一些边界单元测试,以确保.net framework能够像您预期的那样处理精度。
IDbCommand command = GetCommand(); //However you want to implement it.
IDbDataParameter param = command.CreateParameter();
//Or some other method that returns a parameter.
command.Parameters.Add(param);
param.Value = thevalue; //You're value here!