2009-05-15 6 views
9

समान स्कीमा के दो डेटाबेस दिए गए, क्या दोनों के बीच रिकॉर्ड स्थानांतरित करने का कोई आसान तरीका है? मैं LINQ से SQL का उपयोग कर रहा हूं क्योंकि मुझे रास्ते में कुछ अतिरिक्त संचालन करने की आवश्यकता है और मेरे द्वारा स्थानांतरित किए जा रहे रिकॉर्ड का प्रतिनिधित्व करने वाली वस्तुओं को यह बहुत आसान बनाता है। यह एक छोटे पैमाने पर सहायक ऐप है, इसलिए एसएसआईएस शायद अधिक है और SQLBulkCopy मुझे मार्गों में आसानी से पूछताछ करने की अनुमति नहीं देता है।डेटाबेस के बीच प्रतिलिपि बनाने के लिए LINQ से SQL का उपयोग

इस मुझे क्या करना चाहते हैं:

public static void TransferCustomer 
        (DBDataContext DCSource, 
         DBDataContext DCDest, 
         int CustomerID) 
{ 
    Customer customer; 
    using (DCSource = new DBDataContext(SourceConnStr)) 
    { 
    customer = DCSource.Customers 
         .Where(c => c.CustomerID == CustomerID) 
         .Single(); 
    } 

    using (DCDest = new DBDataContext(DestConnStr)) 
    { 
    DCDest.Customers.InsertOnSubmit(customer); 
    DCDest.SubmitChanges(); 
    } 
} 

लेकिन स्पष्ट कारणों के लिए, उस संदेश के साथ एक अपवाद फेंकता है:

का प्रयास संलग्न या एक जोड़े के लिए किया गया है ऐसी इकाई जो नई नहीं है, शायद किसी अन्य डेटा कॉन्टेक्स्ट से लोड हो रही है। यह समर्थित नहीं है।

मैं इस तरह वस्तु का एक उथले नकल करके इस दौर प्राप्त कर सकते हैं:

public static Customer Clone(this Customer customer) 
{ 
    return new Customer() 
    { 
    Name = customer.Name, 
    Email = customer.Email 
    etc... 
    }; 
} 

और फिर क्लोन आइटम डालने। यदि मैं केवल फ़ील्ड को प्रश्न में कॉपी करता हूं, और तालिका संबंधों का प्रतिनिधित्व करने वाले कोई भी संदर्भ यह ठीक काम करता है। हालांकि यह थोड़ा लंबा हवादार है और जिस तरह से मैं कर रहा हूं, मुझे क्लोन विधि में मैन्युअल रूप से प्रत्येक फ़ील्ड को असाइन करने की आवश्यकता है। क्या कोई इसे आसान बनाने के किसी भी तरीके का सुझाव दे सकता है? दो बातें मुझे पता करना चाहते हैं कर रहे हैं:

  1. एसक्यूएल को LINQ कर सकते हैं एक आसान तरीका में ऐसा करते हैं,
  2. वहाँ प्रतिबिंब का उपयोग कर एक उथले प्रति डाल देगा बनाने के लिए का एक अच्छा तरीका है?

बहुत धन्यवाद!

उत्तर

0

क्या यह पूरी तरह से एक अकादमिक व्यायाम है?

यदि नहीं मैं गंभीरता से लघु उद्योगों का उपयोग कर के बारे में सोचना होगा: बजाय http://msdn.microsoft.com/en-us/library/ms141026.aspx, या असफल रहने राइनो ईटीएल कि:। डाटाबेस के बीच http://ayende.com/Blog/archive/2008/01/16/Rhino-ETL-2.0.aspxfor डेटा स्थानांतरित करने [लिंक पाठ] [1]

+1

यह असली है की कोशिश करो, लेकिन यह मुझे इस्तेमाल करने के लिए केवल एक हल्के सहायक अनुप्रयोग है। मैं प्रत्येक बैच में कई तालिकाओं में 50 से अधिक पंक्तियों को स्थानांतरित करने की उम्मीद नहीं करता, इसलिए मुझे लगता है कि एसएसआईएस शायद अधिक है। प्रति ऑब्जेक्ट क्लोन विधि का उपयोग करके मेरा वर्तमान समाधान वास्तव में अच्छी तरह से काम करता है, लेकिन यह सुरुचिपूर्ण लगता है। मुझे कुछ और टेबल जोड़ने की ज़रूरत है, इसलिए मैं क्लोन विधियों को लिखने से पहले एक बेहतर तरीका खोजना चाहता था! –

3

यहाँ उथले क्लोन LINQ वस्तुओं के लिए एक रास्ता है (छोड़ते हुए प्राथमिक कुंजी): Copy Linq Objects

यदि आप विशेषताओं का उपयोग नहीं कर रहे हैं तो इसे मेटा-मॉडल का उपयोग करने के लिए tweaked किया जा सकता है। फिर आपको केवल 2 डेटा-संदर्भ (एक स्रोत, एक गंतव्य) की आवश्यकता होगी।

वैकल्पिक रूप से, आप SqlBulkCopy को देखो सकता है - देखना Copy from one database table to another C#

+0

यह वास्तव में उपयोगी धन्यवाद है। मैं ऑटो-जेनरेटेड इकाई वर्गों का उपयोग कर रहा हूं, इसलिए उनके पास आपके क्लोन विधि का उपयोग करने के लिए आवश्यक सभी मार्कअप हैं। यह अभी भी लगता है कि LINQ से SQL को यह आसान बनाना चाहिए, लेकिन यदि कोई जानता है कि इसे कैसे किया जाए, तो यह मुझे बहुत समय बचाएगा। –

0

क्यों यह करने के लिए LINQ का उपयोग करें? जब आप SQL सर्वर के डीटीएस का उपयोग कर सकते हैं तो रास्ते में आने के लिए ढांचे के लिए यह थोड़ा कचरा लगता है।

+0

आपको डीटीएस की भी आवश्यकता नहीं है; SqlBulkCopy काम करेगा, और कोड की लगभग 5 लाइनें है। –

+0

मुझे रास्ते में कुछ अतिरिक्त संचालन करने में सक्षम होना चाहिए - इस मामले में, इकाई वर्ग होने से मेरे जीवन को अन्य तरीकों से आसान बना दिया जाता है ... मुझे पता है कि रिकॉर्ड रिकॉर्ड करने का यह सबसे अच्छा तरीका नहीं है लेकिन कुछ हैं अन्य कारक जो मुझे LINQ का उपयोग करना चाहते हैं। –

+0

मुझे लगता है कि आप डीटीएस के साथ कस्टम चीजें कर सकते हैं। मुझे यकीन नहीं है कि यह कितना लचीला है। मुझे लगता है कि अगर आपको यहां कोई जवाब नहीं मिलता है तो यह जांच करने लायक है। – uriDium

0

मैं DataContractCloner का उपयोग LINQ करने वाली एसक्यूएल संस्थाओं अलग करने:

/// <summary> 
/// Serializes the entity to XML. 
/// </summary> 
/// <returns>String containing serialized entity.</returns> 
public string Serialize() 
{ 
    return DataContractCloner.Serialize<Organization>(this); 
} 

/// <summary> 
/// Deserializes the entity from XML. 
/// </summary> 
/// <param name="xml">Serialized entity.</param> 
/// <returns>Deserialized entity.</returns> 
public static Organization Deserialize(string xml) 
{ 
    return DataContractCloner.Deserialize<Organization>(xml); 
} 

सभी LINQ करने वाली एसक्यूएल संस्थाओं को पहले से ही टिप्पणी किए गए हैं, इसलिए यह एक कुर्की क्लोन है कि आप बाद में एक साथ फिर से संलग्न कर सकते हैं बनाता है कुछ चेतावनी सबसे पहले, विदेशी कुंजी संबंधों का समाधान किया जाएगा, इसलिए आपको निर्भरता के क्रम में डालना होगा, और यदि आपके पास परिपत्र संबंध हैं तो आपको अपनी स्कीमा से विदेशी कुंजी को हटाना होगा और स्थानांतरण के बाद पुनः आवेदन करना होगा।दूसरा, LINQ-to-SQL एक पहचान सम्मिलित नहीं करता है, इसलिए यदि आप स्वत: वृद्धि पहचान कॉलम का उपयोग कर रहे हैं तो आपको सबमिट करने में समस्याएं आ रही हैं। मुझे डेटा कॉन्टेक्स्ट को पहचान सम्मिलित करने के लिए मजबूर करने में सफलता मिली है, लेकिन वाईएमएमवी।

+0

मूर्ख सवाल शायद, लेकिन DataContractCloner क्या है? मुझे दस्तावेज़ीकरण में कोई संदर्भ नहीं मिल रहा है ... –

+0

हाँ - Google बिल्कुल एक परिणाम बदलता है: यह पृष्ठ! –

0

आप इसके बजाय SQLBulkCopy क्लास का उपयोग करने पर विचार करना चाहेंगे। आप यहां इसके बारे में एक कोड प्रोजेक्ट आलेख पा सकते हैं: http://www.codeproject.com/KB/database/SqlBulkCopy.aspx। यह करने का एक तेज़ तरीका होगा, लेकिन मुझे लगता है कि LINQ-to-SQL को ऐसा करने की बजाय आपको खुद को प्रश्न बनाने की आवश्यकता होगी।

3

इस

using (DCDest = new DBDataContext(DestConnStr)) 
{ 
    DCDest.Customers.InsertOnSubmit(customer.ToList()); //note the use of .ToList() 
    DCDest.SubmitChanges(); 
} 
+0

यह मेरे लिए पूरी तरह से काम किया। धन्यवाद! –

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