불행히도이 매핑이 .NET Framework 내부의 코드에서 노출되지 않는다는 것을 알고있는 한, 불행히도. 이 전에 .NET Framework 참조 소스를 살펴본 결과, .NET 코드 내부에는 피하기 위해 노력하는 것과 같이 긴 per-type switch 문이 많이 있지만 그 중 아무 것도 보이지 않는 것으로 나타났습니다. 외부에 노출 될 수 있습니다.
SqlTypes에서 가장 likley .NET 형식으로 매핑하려는 경우 가장 좋은 방법은 매핑 테이블 in the MSDN docs을 코드로 변환하는 것입니다. MSDN의 테이블에는 적어도 두 가지 오류가 있습니다. # 1 : "DateTime2"라는 .NET 유형이 없습니다 (DateTime 사용). "Xml"(SqlXml 사용) 유형도 없습니다.
어쨌든, 내가 사용해온 매핑은 다음과 같습니다 - 스위치 대신 사전을 사용하여 별도의 방법없이 쉽게 액세스 할 수 있습니다.
public static Dictionary<SqlDbType, Type> TypeMap = new Dictionary<SqlDbType, Type>
{
{ SqlDbType.BigInt, typeof(Int64) },
{ SqlDbType.Binary, typeof(Byte[]) },
{ SqlDbType.Bit, typeof(Boolean) },
{ SqlDbType.Char, typeof(String) },
{ SqlDbType.Date, typeof(DateTime) },
{ SqlDbType.DateTime, typeof(DateTime) },
{ SqlDbType.DateTime2, typeof(DateTime) },
{ SqlDbType.DateTimeOffset, typeof(DateTimeOffset) },
{ SqlDbType.Decimal, typeof(Decimal) },
{ SqlDbType.Float, typeof(Double) },
{ SqlDbType.Int, typeof(Int32) },
{ SqlDbType.Money, typeof(Decimal) },
{ SqlDbType.NChar, typeof(String) },
{ SqlDbType.NText, typeof(String) },
{ SqlDbType.NVarChar, typeof(String) },
{ SqlDbType.Real, typeof(Single) },
{ SqlDbType.SmallInt, typeof(Int16) },
{ SqlDbType.SmallMoney, typeof(Decimal) },
{ SqlDbType.Structured, typeof(Object) }, // might not be best mapping...
{ SqlDbType.Text, typeof(String) },
{ SqlDbType.Time, typeof(TimeSpan) },
{ SqlDbType.Timestamp, typeof(Byte[]) },
{ SqlDbType.TinyInt, typeof(Byte) },
{ SqlDbType.Udt, typeof(Object) }, // might not be best mapping...
{ SqlDbType.UniqueIdentifier, typeof(Guid) },
{ SqlDbType.VarBinary, typeof(Byte[]) },
{ SqlDbType.VarChar, typeof(String) },
{ SqlDbType.Variant, typeof(Object) },
{ SqlDbType.Xml, typeof(SqlXml) },
};
주 당신이 조심해야 한 가지 .NET 유형 (예를 들어, string
)는하지 않지만 크기/precision-- 일부 SQL 유형 (예를 들어, varchar
가), 크기 제한이 있음. 그래서 가장 가능성이있는 .NET 유형을 알 수 있다는 사실만으로는 충분하지 않습니다 ... 예를 들어, 드라이브 유효성 검사 규칙에이 기능을 사용하는 경우 사용자가 유효하지 않은 (예 : 너무 큰) 입력을 방지 할 수 있어야합니다.) 값은 정밀도와 같은 매개 변수에 대해 더 많이 알고 있습니다. SqlClient 소스를 살펴보면 특수 코드를 사용하여 해당 SQL 정밀도에서 Decimal 형식의 정밀도를 설정하는 등의 경우를 처리합니다.
.NET 형식이 필요한 유일한 이유는 저장된 proc 매개 변수에 데이터를 채울 수 있기 때문에 모든 .NET 값에서 ToString()을 사용하고 문자열을 채우고 SqlParameter의 Value 속성을 확인하고 프레임 워크가 변환/구문 분석을 수행하는지 확인합니다. 예를 들어 XML 또는 Date 매개 변수의 경우 문자열 대신 보낼 수 있습니다.
리플렉션을 사용하여 각 유형에 대해 Parse() 메소드를 찾는 대신 알려진 유형의 유형 목록이 있기 때문에 각 유형에 대해 강력한 유형의 구문 분석 코드를 사용하여 성능을 향상시킬 수 있습니다. 아래 코드를 참조하십시오. (몇 가지 유형 (예 : SqlDbType.UDT는) 반드시 당신이 사람들을 처리하는 방법을 파악해야합니다 method-- 명백한 파서이 없습니다.)
public static Dictionary<SqlDbType, Func<string, object>> TypeMapper = new Dictionary<SqlDbType, Func<string, object>>
{
{ SqlDbType.BigInt, s => Int64.Parse(s)},
{ SqlDbType.Binary, s => null }, // TODO: what parser?
{ SqlDbType.Bit, s => Boolean.Parse(s) },
{ SqlDbType.Char, s => s },
{ SqlDbType.Date, s => DateTime.Parse(s) },
{ SqlDbType.DateTime, s => DateTime.Parse(s) },
{ SqlDbType.DateTime2, s => DateTime.Parse(s) },
{ SqlDbType.DateTimeOffset, s => DateTimeOffset.Parse(s) },
{ SqlDbType.Decimal, s => Decimal.Parse(s) },
{ SqlDbType.Float, s => Double.Parse(s) },
{ SqlDbType.Int, s => Int32.Parse(s) },
{ SqlDbType.Money, s => Decimal.Parse(s) },
{ SqlDbType.NChar, s => s },
{ SqlDbType.NText, s => s },
{ SqlDbType.NVarChar, s => s },
{ SqlDbType.Real, s => Single.Parse(s) },
{ SqlDbType.SmallInt, s => Int16.Parse(s) },
{ SqlDbType.SmallMoney, s => Decimal.Parse(s) },
{ SqlDbType.Structured, s => null }, // TODO: what parser?
{ SqlDbType.Text, s => s },
{ SqlDbType.Time, s => TimeSpan.Parse(s) },
{ SqlDbType.Timestamp, s => null }, // TODO: what parser?
{ SqlDbType.TinyInt, s => Byte.Parse(s) },
{ SqlDbType.Udt, s => null }, // consider exception instead
{ SqlDbType.UniqueIdentifier, s => new Guid(s) },
{ SqlDbType.VarBinary, s => null }, // TODO: what parser?
{ SqlDbType.VarChar, s => s },
{ SqlDbType.Variant, s => null }, // TODO: what parser?
{ SqlDbType.Xml, s => s },
};
이상 사용하는 코드를 예를 들면, 매우 간단합니다 :
string valueToSet = "1234";
SqlParameter p = new SqlParameter();
p.SqlDbType = System.Data.SqlDbType.Int;
p.Value = TypeMapper[p.SqlDbType](valueToSet);
정확히하려는 것은 무엇입니까? SqlParameters 컬렉션을 가지고 있고 .net 값의 컬렉션을 가지고있을 때 나는 맞습니까? 그리고 값의 컬렉션을 SqlParameter.Value 속성으로 "변환"하고 싶습니까? 예 : SqlParamaters [0].값 = MagicConvert (값 [0]); – Zenuka