2008-10-19 15 views
9

मैं ASP.NET और एसक्यूएल सर्वर की दुनिया के लिए नया हूँ, इसलिए मेरी अज्ञानता क्षमा करें ...संग्रहीत सी # डेटा एक SQL डेटाबेस में संरचना

अगर मैं (सी # में एक डेटा संरचना है उदाहरण के लिए बस चलो कहें, एक वेक्टर जो कुछ तारों को स्टोर करता है), क्या एसक्यूएल तालिका में वेक्टर की सामग्री को स्टोर करना संभव है? मैं ऐसा करना चाहता हूं ताकि तत्व को तत्व द्वारा तत्व बनाने के बिना जितनी जल्दी हो सके वे डेटा को वेक्टर रूप में परिवर्तित कर सकें। लगभग फ़ाइल में बाइनरी डेटा लिखना और फिर इसे पढ़ना और इसे सी

पर मैंने एक SQL Server 2008 पर एक तालिका बनाई है जिसके लिए एक क्षेत्र VARBINARY (MAX) के रूप में परिभाषित किया गया है। मैंने सोचा कि मैं इसके साथ शुरू करूंगा।

क्या कोई मुझे एक उदाहरण दिखा सकता है कि मैं उस क्षेत्र में और उससे 10 स्ट्रिंग्स के वेक्टर को कहने और पुनर्प्राप्त करने के बारे में कैसे कहूंगा? क्या यह भी संभव है (मैं क्यों नहीं सोच सकता) क्यों?

धन्यवाद!

उत्तर

22

सबसे पहले, एक संबंधपरक संरचना बनाने और डेटाबेस में फ़ील्ड में ऑब्जेक्ट मैप करने का स्पष्ट मार्ग है।

दूसरा, यदि आपके पास कोई ऑब्जेक्ट है जो serializable है, तो आप इसे SQL सर्वर में संग्रहीत कर सकते हैं। मैंने इसे अवसर पर किया है, और एक्सएमएल स्टोर करने के लिए SQL सर्वर में टेक्स्ट डेटा प्रकार का उपयोग किया है।

राय: मैं सीरियलाइज्ड ऑब्जेक्ट्स को बाइनरी डेटा के बजाय एक्सएमएल के रूप में स्टोर करना पसंद करता हूं। क्यों? क्योंकि आप वास्तव में वहां क्या पढ़ सकते हैं (डीबगिंग के लिए), और SQL सर्वर में आप धारावाहिक ऑब्जेक्ट से डेटा का चयन करने के लिए XQuery का उपयोग कर सकते हैं। मेरे अनुभव से, बाइनरी डेटा का उपयोग करने का प्रदर्शन लाभ उस डेटा के मुकाबले लायक नहीं होगा जो डीबग करना आसान है और एक psuedo-relational फैशन में उपयोग किया जा सकता है। SQL Server's XQuery capabilities पर एक नज़र डालें। यहां तक ​​कि यदि आप तुरंत इसका उपयोग करने की योजना नहीं बनाते हैं, तो अपने आप को कोने में रखने का कोई कारण नहीं है।

आप NetDataContractSerializer का उपयोग करके कुछ उदाहरण देख सकते हैं।

मुझे विश्वास है कि आप वेक्टर कहलाते हैं, एक सूची <> सी # में है। System.Collections.Generic में एक नज़र डालें।

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.Serialization; 
using System.IO; 

namespace SerializeThingy 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<string> myList = new List<string>(); 
      myList.Add("One"); 
      myList.Add("Two"); 
      myList.Add("Three"); 
      NetDataContractSerializer serializer = new NetDataContractSerializer(); 
      MemoryStream stream = new MemoryStream(); 
      serializer.Serialize(stream, myList); 
      stream.Position = 0; 
      Console.WriteLine(ASCIIEncoding.ASCII.GetString(stream.ToArray())); 
      List<string> myList2 = (List<string>)serializer.Deserialize(stream); 
      Console.WriteLine(myList2[0]); 
      Console.ReadKey(); 
     } 
    } 
} 

यह उदाहरण सिर्फ एक सूची serializes, कंसोल के लिए क्रमबद्धता आउटपुट, और फिर साबित होता है इसे सही ढंग से दूसरा पहलू पर हाइड्रेटेड गया था: आप की तरह 3 स्ट्रिंग की एक सूची को क्रमानुसार करने NetDataContractSerializer उपयोग कर सकते हैं। मुझे लगता है कि आप देख सकते हैं कि यहां से आप मेमोरी स्ट्रीम को स्ट्रिंग में डंप कर सकते हैं और डेटाबेस में लिख सकते हैं, या इसे करने के लिए मेमोरी स्ट्रीम की तुलना में किसी अन्य स्ट्रीम प्रकार का उपयोग कर सकते हैं।

सिस्टम को संदर्भित करना याद रखें। रनटाइम। NetDataContractSerializer तक पहुंच प्राप्त करने के लिए क्रमबद्धता।

+0

बहुत बढ़िया जवाब, धन्यवाद! – cori

+0

@ जेसन जैक्सन मैं आपसे सहमत हूं, जब आप कहते हैं ** "मैं बाइनरी डेटा के बजाय धारावाहिक वस्तुओं को एक्सएमएल के रूप में स्टोर करना पसंद करता हूं" **, लेकिन अगर मुझे इंटरफेस को क्रमबद्ध करना है तो क्या होगा? – davioooh

+0

इंटरफेस क्रमिक नहीं हैं इसलिए कार्यान्वित गुणों को अनदेखा किया जाना चाहिए ... उपरोक्त विधि कुछ मामलों में बहुत उपयोगी है जहां आपके पास डेटा संरचना निर्माण पर समय लेने वाला संचालन है ... मैं JSON serializer का उपयोग करना पसंद करता हूं जिससे आप स्मृति को सहेज लेंगे ... –

2

यदि आप ऐसा करने वाले हैं (और मुझे लगता है कि यह तकनीकी रूप से संभव) है, तो आप एक फ्लैट फ़ाइल का भी उपयोग कर सकते हैं: अब एक संबंधपरक डेटाबेस का उपयोग करने में कोई बात नहीं है।

+1

तो आप कह रहे हैं कि यदि आपको ऐसा कुछ जारी रखने की आवश्यकता है जो अंतर्निहित डेटाबेस कॉलम प्रकार न हो, तो आपको इसके बजाय फ्लैट फ़ाइलों का उपयोग करना चाहिए? – MusiGenesis

+0

डेटाबेस का उपयोग क्यों नहीं करें? यह निश्चित रूप से एक फ्लैट फ़ाइल की तुलना में अधिक स्केलेबल होने का लाभ है। और यदि आप एक्सएमएल सीरियलाइजेशन प्रारूप का उपयोग करते हैं तो आप XQuery का उपयोग कर SQL सर्वर में डेटा पर भी क्वेरी कर सकते हैं। –

+0

यदि आप डेटाबेस में एक जटिल ऑब्जेक्ट बना रहे हैं, तो ऑब्जेक्ट में प्रत्येक फ़ील्ड को अपना कॉलम या टेबल प्राप्त करना चाहिए ताकि आप उस फ़ील्ड पर खोज और क्वेरी कर सकें। –

3

वस्तुओं को मानते हुए [Serializable] के साथ चिह्नित किया गया है या ISerializable लागू करें BinaryFormatter कक्षा इसे करने का एक आसान तरीका प्रदान करती है।

यदि नहीं, तो आप (गैर तुच्छ) कस्टम कोड देख रहे हैं।

8
[Serializable] 
public struct Vector3 
{ 
    public double x, y, z; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Vector3 vector = new Vector3(); 
     vector.x = 1; 
     vector.y = 2; 
     vector.z = 3; 

     MemoryStream memoryStream = new MemoryStream(); 
     BinaryFormatter binaryFormatter = new BinaryFormatter(); 
     binaryFormatter.Serialize(memoryStream, vector); 
     string str = System.Convert.ToBase64String(memoryStream.ToArray()); 

     //Store str into the database 
    } 
} 
+1

क्यों एक स्ट्रिंग में कनवर्ट करें? उनका स्तंभ बाइनरी है। – MusiGenesis

+1

यदि वह सी से आ रहा है तो एक वेक्टर का अर्थ शायद एक सूची है: http://en.wikipedia.org/wiki/Std::vector –

2

जेनेरिक सूचियों के लिए यहां एक और अधिक सामान्य दृष्टिकोण है। ध्यान दें, वास्तविक प्रकार सूची में संग्रहीत भी serializable

using System.Runtime.Serialization.Formatters.Binary; 
using System.IO; 
using System.Data.SqlClient; 
using System.Runtime.Serialization; 

public byte[] SerializeList<T>(List<T> list) 
{ 

    MemoryStream ms = new MemoryStream(); 

    BinaryFormatter bf = new BinaryFormatter(); 

    bf.Serialize(ms, list); 

    ms.Position = 0; 

    byte[] serializedList = new byte[ms.Length]; 

    ms.Read(serializedList, 0, (int)ms.Length); 

    ms.Close(); 

    return serializedList; 

} 

public List<T> DeserializeList<T>(byte[] data) 
{ 
    try 
    { 
     MemoryStream ms = new MemoryStream(); 

     ms.Write(data, 0, data.Length); 

     ms.Position = 0; 

     BinaryFormatter bf = new BinaryFormatter(); 

     List<T> list = bf.Deserialize(ms) as List<T>; 

     return list; 
    } 
    catch (SerializationException ex) 
    { 
     // Handle deserialization problems here. 
     Debug.WriteLine(ex.ToString()); 

     return null; 
    } 

} 

तो ग्राहक कोड में होना चाहिए:

List<string> stringList = new List<string>() { "January", "February", "March" }; 

byte[] data = SerializeList<string>(stringList); 

एक भंडारण की बुनियादी तरीका/बाइट्स की इस सरणी पुन: प्राप्त करने के लिए सरल SqlClient वस्तुओं का उपयोग करने के किया जा सकता है :

SqlParameter param = new SqlParameter("columnName", SqlDbType.Binary, data.Length); 
param.Value = data; 

etc... 
0

मैं ग # से रिलेशनल डेटाबेस के साथ और अधिक अनुभव है, लेकिन द्विआधारी क्रमांकन, जाने के लिए एक स्वीकार्य तरीका है के रूप में यह अनुमति देता है संपूर्ण वस्तु के राज्य पूर्णांक बचाया जा ओ डेटाबेस। एक्सएमएल क्रमबद्धता काफी समान है, हालांकि सामान्य प्रकारों की अनुमति नहीं है।

+0

मामूली सुधार: सामान्य प्रकार की अनुमति है, यदि आप डेटाकंट्रैक क्रमबद्धरण या नेटडाटा कंट्रैक्ट क्रमबद्धता का उपयोग करते हैं, बल्कि एक्सएमएल क्रमिकरण से। –

1

लचीला होने के कारण हैं। डेटाबेस संरचना के लिए नियम, या दिशानिर्देशों को रचनात्मकता में बाधा डालने की अनुमति नहीं दी जानी चाहिए। यहां पहले धागे को देखते हुए, मैं दोनों धारावाहिक और बाधा कॉलम को संग्रहीत करने के लिए एक संकर दृष्टिकोण देख सकता हूं। कई लोगों को दिमाग को संभावनाओं के लिए खुले रखकर बहुत अधिक आवेदन किया जा सकता है।

वैसे भी, मैंने इस मामले पर एक नए परिप्रेक्ष्य की सराहना की। हमें सभी ताजा रखता है ..

संबंधित मुद्दे