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);




system.data