2008-09-19 10 views
11

मैं जानना चाहता हूं कि रिकॉर्ड डालने का कोई आसान तरीका है यदि यह तालिका में पहले से मौजूद नहीं है। मैं अभी भी अपने LINQ को SQL कौशल में बनाने की कोशिश कर रहा हूं।LINQ से SQL सम्मिलित-अगर-अस्तित्वहीन

यहां मुझे जो मिला है, लेकिन ऐसा लगता है कि एक आसान तरीका होना चाहिए।

public static TEntity InsertIfNotExists<TEntity> 
(
    DataContext db, 
    Table<TEntity> table, 
    Func<TEntity,bool> where, 
    TEntity record 
) 
    where TEntity : class 
{ 
    TEntity existing = table.SingleOrDefault<TEntity>(where); 

    if (existing != null) 
    { 
     return existing; 
    } 
    else 
    { 
     table.InsertOnSubmit(record); 

     // Can't use table.Context.SubmitChanges() 
     // 'cause it's read-only 

     db.SubmitChanges(); 
    } 

    return record; 
} 

उत्तर

14
public static void InsertIfNotExists<TEntity> 
        (this Table<TEntity> table, 
        TEntity entity, 
        Expression<Func<TEntity,bool>> predicate) 
    where TEntity : class 
{ 
    if (!table.Any(predicate)) 
    { 
     table.InsertOnSubmit(record); 
     table.Context.SubmitChanges(); 
    } 
} 


table.InsertIfNotExists(entity, e=>e.BooleanProperty); 
+0

e => e.BooleanProperty क्या है? संस्थाओं में एक बूलियन प्रॉपर्टी सदस्य नहीं है। मैंने इसे पहले कभी नहीं देखा है ... – core

+0

हम्म, आप देखेंगे कि मेरे कोड में, मैंने कहा कि तालिका। कॉन्टैक्ट। सबमिट चेंज() काम नहीं कर रहा क्योंकि यह केवल-प्राप्त है। जाहिर है मैंने गलती की। – core

+0

ई => ई। बोलेनप्रोपर्टी सिर्फ एक उदाहरण है। यह किसी भी अभिव्यक्ति के लिए खड़ा हो सकता है जो एक बूलियन मान देता है। –

4

marxidad's answer के साथ सहमत, लेकिन ध्यान दें 1.

नोट 1 देखें: IMHO, यह एक सहायक विधि में db.SubmitChanges() कॉल करने के लिए है, क्योंकि आप संदर्भ लेन-देन टूट सकता है समझदारी नहीं है। इसका अर्थ यह है कि यदि आप कई इकाइयों के जटिल अद्यतन के बीच InsertIfNotExists<TEntity> पर कॉल करते हैं तो आप परिवर्तनों को एक बार में नहीं बल्कि कदमों में सहेज रहे हैं।

नोट 2: InsertIfNotExists<TEntity> विधि एक बहुत ही सामान्य विधि है जो किसी भी परिदृश्य के लिए काम करती है। तुम सिर्फ संस्थाओं है कि संस्थाओं है कि कोड से निर्मित किया गया है से डेटाबेस से भरी हुई है भेदभाव करने के लिए चाहते हैं, तो आप इस तरह इकाई वर्ग के आंशिक विधि OnLoaded उपयोग कर सकते हैं:

public partial class MyEntity 
{ 
    public bool IsLoaded { get; private set; } 
    partial void OnLoaded() 
    { 
     IsLoaded = true; 
    } 
} 

यह देखते हुए कि (और नोट 1), तो InsertIfNotExists कार्यक्षमता के लिए कम हो जाता है निम्नलिखित:

if (!record.IsLoaded) 
    db.InsertOnSubmit(record); 
+2

InsertOnSubmitIfNotExists() और टेबल छोड़ने के तरीके के लिए एक बेहतर डिज़ाइन हो सकता है। कॉन्टैक्ट। सबमिशन चेंज() –

4
मार्क जवाब के लिए

छोटे संशोधन:

आप केवल जाँच इकाई अपनी प्राथमिक कुंजी, Marke का जवाब कर सकते हैं से मौजूद है, तो ध्यान देते हैं इस तरह इस्तेमाल किया जा:

public static void InsertIfNotExists<TEntity> 
        (this Table<TEntity> table 
        , TEntity entity 
        ) where TEntity : class 
    { 
     if (!table.Contains(entity)) 
     { 
      table.InsertOnSubmit(entity); 

     } 
    } 
11

के रूप में अन्य लोगों ने बताया है, if (!Any()) { InsertOnSubmit(); } समाधान सब एक रेस स्थिति है। यदि आप उस मार्ग पर जाते हैं, जब आप SubmitChanges पर कॉल करते हैं, तो आपको यह ध्यान रखना होगा कि या तो ए) एक SqlException डुप्लिकेट डालने के लिए उठाया जा सकता है, या बी) आप तालिका में डुप्लिकेट रिकॉर्ड प्राप्त कर सकते हैं।

सौभाग्य से, हम विशिष्टता को लागू करके दौड़ की स्थिति से बचने के लिए डेटाबेस का उपयोग कर सकते हैं। निम्न कोड मानता है कि डुप्लिकेट रिकॉर्ड को सम्मिलित करने से रोकने के लिए तालिका पर प्राथमिक कुंजी या अद्वितीय बाधा है।

using (var db = new DataContext()) { 

    // Add the new (possibly duplicate) record to the data context here. 

    try { 
     db.SubmitChanges(); 
    } catch (SqlException ex) { 
     const int violationOfPrimaryKeyContraint = 2627; 
     const int violationOfUniqueConstraint = 2601; 
     var duplicateRecordExceptionNumbers = new [] { 
      violationOfPrimaryKeyContraint, violationOfUniqueConstraint 
     }; 
     if (!duplicateRecordExceptionNumbers.Contains(ex.Number)) { 
      throw; 
     } 
    } 
} 

अब ... बातें एक निष्पक्ष थोड़ा और अधिक जटिल हो आप अन्य डेटाबेस अद्यतन के साथ एक बैच सौदे में डालने प्रदर्शन करने के लिए किया है।