2009-06-17 9 views
7

हल करने की कोशिश में:लिंक में अस्थायी सारणी - किसी को भी इस में कोई समस्या दिखाई देती है?

Linq .Contains with large set causes TDS error

मुझे लगता है कि मैं एक समाधान भर में ठोकर खाई है, और मैं अगर यह समस्या आ के एक कोषेर तरीका है देखना चाहते हैं।

(लघु सारांश) मैं SQL आईडी में उत्पन्न (पूरी तरह से या कम से कम आसानी से) रिकॉर्ड आईडी की सूची के खिलाफ linq-join करना चाहता हूं। यह एक बड़ी सूची है और अक्सर टीडीएस आरपीसी कॉल के लिए 2100 आइटम सीमा से पहले उड़ाती है। तो मैंने एसक्यूएल में जो किया होगा उसे एक अस्थायी तालिका में फेंक दिया जाता है, और फिर जब मुझे उनकी आवश्यकता होती है तो उसके खिलाफ शामिल हो जाती है।

तो मैंने लिंक में भी ऐसा ही किया।

मेरी MyDB.dbml फ़ाइल में मैं कहा:

<Table Name="#temptab" Member="TempTabs"> 
    <Type Name="TempTab"> 
    <Column Name="recno" Type="System.Int32" DbType="Int NOT NULL" 
      IsPrimaryKey="true" CanBeNull="false" /> 
    </Type> 
</Table> 

डिजाइनर खोलने और बंद करने यह वहाँ आवश्यक प्रविष्टियों जोड़ा है, हालांकि संपूर्णता के लिए, मैं MyDB.desginer.cs फ़ाइल से बोली जाएगा:

[Table(Name="#temptab")] 
    public partial class TempTab : INotifyPropertyChanging, INotifyPropertyChanged 
    { 

      private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty); 

      private int _recno; 

#region Extensibility Method Definitions 
partial void OnLoaded(); 
partial void OnValidate(System.Data.Linq.ChangeAction action); 
partial void OnCreated(); 
partial void OnrecnoChanging(int value); 
partial void OnrecnoChanged(); 
#endregion 

      public TempTab() 
      { 
        OnCreated(); 
      } 

      [Column(Storage="_recno", DbType="Int NOT NULL", IsPrimaryKey=true)] 
      public int recno 
      { 
        get 
        { 
          return this._recno; 
        } 
        set 
        { 
          if ((this._recno != value)) 
          { 
            this.OnrecnoChanging(value); 
            this.SendPropertyChanging(); 
            this._recno = value; 
            this.SendPropertyChanged("recno"); 
            this.OnrecnoChanged(); 
          } 
        } 
      } 

      public event PropertyChangingEventHandler PropertyChanging; 

      public event PropertyChangedEventHandler PropertyChanged; 

      protected virtual void SendPropertyChanging() 
      { 
        if ((this.PropertyChanging != null)) 
        { 
          this.PropertyChanging(this, emptyChangingEventArgs); 
        } 
      } 

      protected virtual void SendPropertyChanged(String propertyName) 
      { 
        if ((this.PropertyChanged != null)) 
        { 
          this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
        } 
      } 
    } 

फिर यह कोड में कुछ चीजों के आसपास जॉगलिंग का मामला बन गया। कहाँ मैं सामान्य रूप से पड़ा है चाहते हैं:

MyDBDataContext mydb = new MyDBDataContext(); 

मैं इतना है कि मैं कनेक्शन इस्तेमाल कर सकते हैं अस्थायी तालिका बनाने के लिए यह एक सामान्य SqlConnection के साथ अपने कनेक्शन साझा करने के पाने के लिए था। उसके बाद यह काफी उपयोगी लगता है।

string connstring = "Data Source.... etc.."; 
SqlConnection conn = new SqlConnection(connstring); 
conn.Open(); 

SqlCommand cmd = new SqlCommand("create table #temptab " + 
           "(recno int primary key not null)", conn); 
cmd.ExecuteNonQuery(); 

MyDBDataContext mydb = new MyDBDataContext(conn); 
// Now insert some records (1 shown for example) 
TempTab tt = new TempTab(); 
tt.recno = 1; 
mydb.TempTabs.InsertOnSubmit(tt); 
mydb.SubmitChanges(); 

और इसे का उपयोग:

// Through normal SqlCommands, etc... 
cmd = new SqlCommand("select top 1 * from #temptab", conn); 
Object o = cmd.ExecuteScalar(); 

// Or through Linq 
var t = from tx in mydb.TempTabs 
     from v in mydb.v_BigTables 
     where tx.recno == v.recno 
     select tx; 

किसी को भी अस्थायी तालिकाओं का उपयोग Linq में मिलती है में के लिए एक सामान्य प्रयोजन समाधान के रूप में इस दृष्टिकोण के साथ कोई समस्या दिखाई देती है?

यह मेरी समस्या को आश्चर्यजनक ढंग से हल करता है, क्योंकि अब मैं उपयोग करने के बजाय लिंक में सीधा साझेदारी कर सकता हूं। कॉन्टैन्स()।

पोस्टस्क्रिप्ट: एक समस्या मुझे क्या करना है कि मेज पर Linq और नियमित रूप से SqlCommands मिश्रण (जहां एक/लेखन पढ़ने और इसलिए है अन्य है) खतरनाक हो सकता है। टेबल पर सम्मिलित करने के लिए हमेशा SqlCommands का उपयोग करके, और फिर इसे पढ़ने के लिए लिंक कमांड ठीक काम करता है। जाहिर है, लिंक कैश के परिणाम - शायद इसके चारों ओर एक रास्ता है, लेकिन यह स्पष्ट नहीं था।

उत्तर

3

मुझे आपकी समस्या का समाधान करने के लिए अस्थायी तालिकाओं का उपयोग करने में कोई समस्या नहीं दिखाई दे रही है। जहां तक ​​SqlCommands और LINQ मिश्रण करते हैं, आप खतरे के कारक के बारे में बिल्कुल सही हैं। यह तो एक DataContext का उपयोग कर अपने SQL कथन निष्पादित करने के लिए आसान है, मैं भी SqlCommand के बारे में चिंता नहीं करता:

private string _ConnectionString = "<your connection string>"; 

public void CreateTempTable() 
{ 
    using (MyDBDataContext dc = new MyDBDataContext(_ConnectionString)) 
    { 
     dc.ExecuteCommand("create table #temptab (recno int primary key not null)"); 
    } 
} 

public void DropTempTable() 
{ 
    using (MyDBDataContext dc = new MyDBDataContext(_ConnectionString)) 
    { 
     dc.ExecuteCommand("DROP TABLE #TEMPTAB"); 
    } 
} 

public void YourMethod() 
{ 
    CreateTempTable(); 

    using (MyDBDataContext dc = new MyDBDataContext(_ConnectionString)) 
    { 
     ... 
     ... do whatever you want (within reason) 
     ... 
    } 

    DropTempTable(); 
} 
0

एक "सामान्य प्रयोजन समाधान", यदि आप कोड एक से अधिक धागे में चलाया जाता है क्या के रूप में/क्षुधा? मुझे लगता है कि बड़े सूची समाधान हमेशा समस्या डोमेन से संबंधित है। जिस समस्या पर आप काम कर रहे हैं उसके लिए एक नियमित तालिका का उपयोग करना बेहतर है।

मैंने डेटाबेस में "जेनेरिक" सूची तालिका बनाई है। तालिका को तीन स्तंभों के साथ बनाया गया था: int, uniqueidentifier और varchar, प्रत्येक सूची को प्रबंधित करने के लिए अन्य कॉलम के साथ। मैं सोच रहा था: "यह कई मामलों को संभालने के लिए पर्याप्त होना चाहिए"। लेकिन जल्द ही मुझे एक ऐसा कार्य प्राप्त हुआ जिसके लिए तीन पूर्णांकों पर एक सूची के साथ शामिल होने की आवश्यकता है।उसके बाद, मैंने कभी भी "जेनेरिक" सूची तालिका बनाने की कोशिश नहीं की।

साथ ही, प्रत्येक डेटाबेस कॉल में सूची तालिका में एकाधिक आइटम डालने के लिए एसपी बनाना बेहतर है। आप आसानी से 2 डीबी दौर यात्राओं में ~ 2000 आइटम डाल सकते हैं। कारण के आधार पर, आप जो कर रहे हैं उसके आधार पर, प्रदर्शन कोई फर्क नहीं पड़ता।

संपादित करें: भूल गया है कि यह एक अस्थायी तालिका है और अस्थायी तालिका प्रति कनेक्शन है, इसलिए बहु-धागे पर मेरा पिछला तर्क उचित नहीं था। लेकिन फिर भी, यह निश्चित स्कीमा लागू करने के लिए एक सामान्य समाधान नहीं है।

1

हमारे पास एक समान स्थिति है, और यह काम करता है, यह मुद्दा बन जाता है कि आप वास्तव में क्वेरीबेल से निपट नहीं रहे हैं, इसलिए आप आसानी से "LIN" के साथ इसका उपयोग नहीं कर सकते हैं। यह एक समाधान नहीं है जो विधि श्रृंखलाओं के साथ काम करता है।

हमारा अंतिम समाधान केवल एक संग्रहीत प्रक्रिया में जो चाहते हैं उसे फेंकने के लिए था, और जब हम उन मूल्यों को चाहते हैं तो temp तालिकाओं के खिलाफ उस प्रक्रिया में चयन लिखते हैं। यह एक समझौता है, लेकिन दोनों कामकाज हैं। कम से कम संग्रहित प्रो के साथ डिज़ाइनर आपके लिए कॉलिंग कोड उत्पन्न करेगा, और आपके पास ब्लैक बॉक्सिंग कार्यान्वयन होगा, इसलिए यदि आपको और ट्यूनिंग करने की आवश्यकता है तो आप प्रक्रिया के भीतर कड़ाई से ऐसा कर सकते हैं, बिना किसी प्रतिकृति के।

एक परिपूर्ण दुनिया में, लिंकक 2 एसक्यूएल स्टेटमेंट्स लिखने के लिए कुछ भविष्य का समर्थन होगा जो आपको अपने प्रश्नों के भीतर अस्थायी सारणी के उपयोग को नाजुक करने की अनुमति देता है, इस तरह के जटिल परिदृश्यों के लिए ग़लत एसक्यूएल इन स्टेटमेंट से बचें।

0

क्या नील द्वारा प्रदान किया गया समाधान वास्तव में काम करेगा? यदि यह एक अस्थायी तालिका है, और प्रत्येक विधि अपने डेटा संदर्भ को बना रही है और उसका निपटान कर रही है, तो मुझे नहीं लगता कि कनेक्शन गिरने के बाद भी अस्थायी तालिका होगी।

भले ही यह वहां था, मुझे लगता है कि यह एक ऐसा क्षेत्र होगा जहां आप कुछ कार्यक्षमताओं को मानते हैं कि प्रश्न और कनेक्शन कैसे प्रदान किए जा रहे हैं, और लिनक के साथ बड़े मुद्दों के बारे में पता है - आप बस नहीं जानते कि क्या हो सकता है कि वह ट्रैक कर सके क्योंकि इंजीनियरों चीजों को करने के बेहतर तरीके से आते हैं।

मैं इसे एक संग्रहित प्रो में करूँगा। यदि आप चाहें तो आप हमेशा परिणाम सेट को प्री-डिफ़ाइंड टेबल में वापस कर सकते हैं।

+0

ईमानदार होने के लिए, मैंने अस्थायी तालिकाओं का उपयोग करके प्रदान किए गए समाधान का परीक्षण नहीं किया है। कहा जा रहा है, समाधान निश्चित रूप से "स्थायी" टेबल का उपयोग कर काम करेगा। इसके अतिरिक्त, मैं DataContext.ExecuteCommand() विधि का उपयोग कर रहा हूं क्योंकि SQL कथन को LINQ इंजन द्वारा बिल्कुल नियंत्रित नहीं किया जाता है ... जो आप भेजते हैं वह है जो चल रहा है। –

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

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