Sim*_*lvo 14 c# ado.net system.data
我正在寻找.Net System.Type和SqlDbType之间的智能转换.我发现它是以下想法:
private static SqlDbType TypeToSqlDbType(Type t)
{
String name = t.Name;
SqlDbType val = SqlDbType.VarChar; // default value
try
{
if (name.Contains("16") || name.Contains("32") || name.Contains("64"))
{
name = name.Substring(0, name.Length - 2);
}
val = (SqlDbType)Enum.Parse(typeof(SqlDbType), name, true);
}
catch (Exception)
{
// add error handling to suit your taste
}
return val;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不是很好,是一个代码气味,这就是为什么我写了以下,天真,不聪明,但有用的功能,基于https://msdn.microsoft.com/en-us/library/cc716729( v = vs.110).aspx:
public static SqlDbType ConvertiTipo(Type giveType)
{
var typeMap = new Dictionary<Type, SqlDbType>();
typeMap[typeof(string)] = SqlDbType.NVarChar;
typeMap[typeof(char[])] = SqlDbType.NVarChar;
typeMap[typeof(int)] = SqlDbType.Int;
typeMap[typeof(Int32)] = SqlDbType.Int;
typeMap[typeof(Int16)] = SqlDbType.SmallInt;
typeMap[typeof(Int64)] = SqlDbType.BigInt;
typeMap[typeof(Byte[])] = SqlDbType.VarBinary;
typeMap[typeof(Boolean)] = SqlDbType.Bit;
typeMap[typeof(DateTime)] = SqlDbType.DateTime2;
typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
typeMap[typeof(Decimal)] = SqlDbType.Decimal;
typeMap[typeof(Double)] = SqlDbType.Float;
typeMap[typeof(Decimal)] = SqlDbType.Money;
typeMap[typeof(Byte)] = SqlDbType.TinyInt;
typeMap[typeof(TimeSpan)] = SqlDbType.Time;
return typeMap[(giveType)];
}
Run Code Online (Sandbox Code Playgroud)
有人知道如何以更清洁,更好,更好的方式获得相同的结果吗?
And*_*lad 17
你的方法是一个良好的开端,但填充该字典应该只进行一次,正如伊恩在评论中所说.
这里有一个GIST基于相同的想法,虽然它不会在相同的类型集之间进行转换:https://gist.github.com/abrahamjp/858392
警告
我在下面有一个工作示例,但您需要注意这种方法确实存在一些问题.例如:
string
,你如何挑选之间正确的Char
,NChar
,VarChar
,NVarChar
,Text
或NText
(甚至Xml
,也许)?byte[]
,你应该使用Binary
,VarBinary
还是Image
?decimal
,float
和double
,你应该去Decimal
,Float
,Money
,SmallMoney
或Real
?DateTime
,你需要DateTime2
,DateTimeOffset
,DateTime
,或SmallDateTime
?Nullable
类型int?
吗?那些应该最有可能SqlDbType
与底层类型相同.此外,只提供一个Type
告诉你其他约束,如字段大小和精度.做出正确的决定还涉及如何在您的应用程序中使用数据以及如何将数据存储在数据库中.
最好的办法是让ORM为你做这件事.
码
public static class SqlHelper
{
private static Dictionary<Type, SqlDbType> typeMap;
// Create and populate the dictionary in the static constructor
static SqlHelper()
{
typeMap = new Dictionary<Type, SqlDbType>();
typeMap[typeof(string)] = SqlDbType.NVarChar;
typeMap[typeof(char[])] = SqlDbType.NVarChar;
typeMap[typeof(byte)] = SqlDbType.TinyInt;
typeMap[typeof(short)] = SqlDbType.SmallInt;
typeMap[typeof(int)] = SqlDbType.Int;
typeMap[typeof(long)] = SqlDbType.BigInt;
typeMap[typeof(byte[])] = SqlDbType.Image;
typeMap[typeof(bool)] = SqlDbType.Bit;
typeMap[typeof(DateTime)] = SqlDbType.DateTime2;
typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
typeMap[typeof(decimal)] = SqlDbType.Money;
typeMap[typeof(float)] = SqlDbType.Real;
typeMap[typeof(double)] = SqlDbType.Float;
typeMap[typeof(TimeSpan)] = SqlDbType.Time;
/* ... and so on ... */
}
// Non-generic argument-based method
public static SqlDbType GetDbType(Type giveType)
{
// Allow nullable types to be handled
giveType = Nullable.GetUnderlyingType(giveType) ?? giveType;
if (typeMap.ContainsKey(giveType))
{
return typeMap[giveType];
}
throw new ArgumentException($"{giveType.FullName} is not a supported .NET class");
}
// Generic version
public static SqlDbType GetDbType<T>()
{
return GetDbType(typeof(T));
}
}
Run Code Online (Sandbox Code Playgroud)
这就是你如何使用它:
var sqlDbType = SqlHelper.GetDbType<string>();
// or:
var sqlDbType = SqlHelper.GetDbType(typeof(DateTime?));
// or:
var sqlDbType = SqlHelper.GetDbType(property.PropertyType);
Run Code Online (Sandbox Code Playgroud)
mpa*_*pag 10
看起来这种查找表已经可用,尽管不在System.Data
(或.Object
或.Type
)中,而是在 System.Web 中。
项目 -> 添加引用 -> System.Web -> 确定
然后https://msdn.microsoft.com/en-us/library/system.data.sqldbtype(v=vs.110).aspx也说
设置命令参数时,SqlDbType 和 DbType 是链接的。因此,设置 DbType 会将 SqlDbType 更改为支持的 SqlDbType。
所以,这在理论上应该有效;)
using Microsoft.SqlServer.Server; // SqlDataRecord and SqlMetaData
using System;
using System.Collections; // IEnumerator and IEnumerable
using System.Collections.Generic; // general IEnumerable and IEnumerator
using System.Data; // DataTable and SqlDataType
using System.Data.SqlClient; // SqlConnection, SqlCommand, and SqlParameter
using System.Web.UI.WebControls; // for Parameters.Convert... functions
private static SqlDbType TypeToSqlDbType(Type t) {
DbType dbtc = Parameters.ConvertTypeCodeToDbType(t.GetTypeCodeImpl());
SqlParameter sp = new SqlParameter();
// DbParameter dp = new DbParameter();
// dp.DbType = dbtc;
sp.DbType = dbtc;
return sp.SqlDbType;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14624 次 |
最近记录: |