c# - एसक्यूएलडीबी टाइप करने के लिए.NET सिस्टम प्रकार
ado.net system.data (2)
संपादित करें: मैं सिस्टम के बारे में सोच रहा था और यह काम करता है। Data.SqlTypes प्रकार मैं इसे यहाँ छोड़ दूँगा अगर यह भविष्य में किसी को मदद करता है।
मैं ऐसा कुछ करता हूं:
object objDbValue = DbReader.GetValue(columnIndex);
Type sqlType = DbReader.GetFieldType(columnIndex);
Type clrType = null;
if (sqlType.Name.StartsWith("Sql"))
{
var objClrValue = objDbValue.GetType()
.GetProperty("Value")
.GetValue(objDbValue, null);
clrType = objClrValue.GetType();
}
क्योंकि हर SqlDbType में एक वास्तविक मूल्य है जो वास्तविक अंतर्निहित CLR प्रकार है I इसे प्राप्त करने के लिए प्रतिबिंब का उपयोग करता है। यह बहुत बुरा है SqlDbType के पास कुछ इंटरफ़ेस नहीं है जो इसे रखेगा। मूल्य संपत्ति और प्रतिबिंब की आवश्यकता नहीं होगी।
यह सही नहीं है, लेकिन आपको मैन्युअल रूप से एक शब्दकोश बनाने, रखरखाव या आबाद करने की आवश्यकता नहीं है। आप किसी मौजूदा शब्द में बस एक प्रकार की खोज कर सकते हैं, और यदि वह मौजूद नहीं है, तो मैपिंग स्वचालित रूप से जोड़ने के लिए ऊपरी विधि का उपयोग करें। बहुत ज्यादा ऑटो जनरेटेड
इसके अलावा किसी भी नए प्रकार का ध्यान रखता है, जिसे भविष्य में SQL सर्वर प्राप्त हो सकता है।
मैं नेट सिस्टम.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;
}
उपरोक्त कोड वास्तव में अच्छा नहीं है और यह कोड गंध है, यही कारण है कि मैंने निम्नलिखित, भोलेदार, स्मार्ट, लेकिन उपयोगी फ़ंक्शन, 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)];
}
क्या किसी को यह पता चलता है कि क्लीनर, बेहतर और अच्छे तरीके से एक ही परिणाम कैसे प्राप्त किया जाए?
आपका दृष्टिकोण एक अच्छी शुरुआत है, लेकिन यह प्रचलित है कि शब्दकोश केवल एक बार किया जाना चाहिए, जैसा कि इयान एक टिप्पणी में कहते हैं।
यहां एक गिस्ट है जो कि एक ही विचार पर आधारित है, हालांकि यह उसी प्रकार के सेटों के बीच परिवर्तित नहीं होता: https://gist.github.com/abrahamjp/858392
चेतावनी
मेरे पास नीचे एक कामकाज उदाहरण है, लेकिन आपको इस बात से अवगत होना चाहिए कि इस दृष्टिकोण में कुछ समस्याएं हैं उदाहरण के लिए:
- एक
string
, आपChar
,NChar
,NChar
,NChar
,Text
याNText
(या यहां तक किXml
, के बीच) के बीच सही कैसे चुन सकते हैं? - और
byte[]
जैसी ब्लॉप्स के लिए, क्या आपकोBinary
,VarBinary
याImage
इस्तेमाल करना चाहिए? -
decimal
,float
औरdouble
, क्या आपकोDecimal
,Float
,Money
,SmallMoney
Money
याReal
लिए जाना चाहिए? -
DateTime
, क्या आपकोDateTime2
,DateTimeOffset
SmallDateTime
,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));
}
}
और यह है कि आप इसका उपयोग कैसे करेंगे:
var sqlDbType = SqlHelper.GetDbType<string>();
// or:
var sqlDbType = SqlHelper.GetDbType(typeof(DateTime?));
// or:
var sqlDbType = SqlHelper.GetDbType(property.PropertyType);