LINQ में इकाइयों को थोक में हटाना


82

LINQ या LINQ-to-Entities में दिए गए क्वेरी से मेल खाने वाली वस्तुओं के एक समूह को थोक में हटाने का कोई तरीका है? केवल संदर्भ जो मुझे मिल सकते हैं वे पुराने हैं, और यह मूर्खतापूर्ण लगता है कि मैं इसे खत्म करना चाहता हूं और मैन्युअल रूप से उन सभी वस्तुओं को हटा देता हूं जिन्हें मैं हटाना चाहता हूं।

जवाबों:


30

प्रश्न एक पुराना है (EF5 अस्तित्व में होने से पहले)। EF5, EntityFramework.Extended का उपयोग करने वाले किसी भी व्यक्ति के लिए यह एक तस्वीर में है।


53

थोड़ी देर पहले मैंने एक 4 भाग की ब्लॉग श्रृंखला (भाग 1 , 2 , 3 और 4 ) लिखी थी , जिसमें एंटिटी फ्रेमवर्क में बल्क अपडेट (एक कमांड के साथ) कर रहे थे।

जबकि उस श्रृंखला का फोकस अपडेट था, आप निश्चित रूप से डिलीट करने के लिए शामिल सिद्धांतों का उपयोग कर सकते हैं।

तो आपको इस तरह से कुछ लिखने में सक्षम होना चाहिए:

var query = from c in ctx.Customers
            where c.SalesPerson.Email == "..."
            select c;

query.Delete();

आपको केवल डिलीट () एक्सटेंशन पद्धति को लागू करना होगा। कैसे पर संकेत के लिए पोस्ट श्रृंखला देखें ...

उम्मीद है की यह मदद करेगा


17
अगर किसी के पास है तो इसके लिए एक कोड सैंपल रखना अच्छा होगा!
jocull

1
विस्तार विधियों का एक गुच्छा (एक बैच डिलीट सहित) यहां पाया जा सकता है: github.com/loresoft/EntityFramework.Extended
सोलियाह

1
खबरदार github.com/loresoft/EntityFramework.Extended पर EF5 पर निर्भरता है, यदि आप इसे स्थापित करने के लिए Nuget पैकेज प्रबंधक कंसोल का उपयोग करते हैं, तो यह आपसे EF5 स्थापित करने के बिना होगा
पॉल Zahin

1
यह वास्तव में मदद नहीं करता है - मैं एक डिलीट कमांड का कार्यशील उदाहरण देखना चाहूंगा और "अनुमान" नहीं लगाऊंगा कि कैसे उत्पादन कोड में खुद को लागू किया जाए और संभवत: कुछ को स्क्रू किया जाए। -1
नाज़ोलिलो

27
हम्म ... इसलिए सवाल का जवाब दर्शकों के लिए विशिष्ट जवाब पेश करने के बजाय 4 ब्लॉग पोस्ट पर रीडायरेक्ट करना है।
दीपस्पेस101101

41
    using (var context = new DatabaseEntities())
    {
        // delete existing records
        context.ExecuteStoreCommand("DELETE FROM YOURTABLE WHERE CustomerID = {0}", customerId);
    }


2
मुझे एहसास है कि ऐसा करने का शायद एकमात्र तरीका है, एक संग्रहीत प्रक्रिया बनाने की कमी, लेकिन यह धोखा =) जैसा लगता है। अब जब कि मैं इस का उपयोग कर रहा हूँ, मैं इसे कई अन्य स्थानों पर उपयोग करने का प्रलोभन देता हूँ EF की विचित्रता को शांत करने के लिए - जैसे कि जटिल बाएँ
जोड़

+! ... एक DB का उपयोग करते समय, आप पाएंगे कि आपको जो उपकरण चाहिए वह एक पेचकश है .. EF सिर्फ एक और हथौड़ा है।
gbjbaanb

2
थोड़ा नीचे की ओर: अब आपके पास एक डेटाबेस कमांड है जो विकास पर्यावरण से डिस्कनेक्ट है। यह दृढ़ता से टाइप नहीं किया गया है, इसलिए इस एसक्यूएल में कॉलम के लिए डेटाबेस में परिवर्तन को विजुअल स्टूडियो में उजागर नहीं किया जाएगा
इयान

7

मैं यहां जो उत्तर देख रहा हूं, वह लिनक से सकल हैं

DeleteAllOnSubmit System.Data.Linq और ITable का हिस्सा है जो कि Sql का Linq है

यह एंटिटी फ्रेमवर्क के साथ नहीं किया जा सकता है।

सभी ने कहा कि मेरे पास अभी तक कोई समाधान नहीं है, लेकिन जब मैं करूंगा तब वापस पोस्ट करूंगा


5

EF6 का उपयोग करने वालों और हटाने के लिए पंक्ति SQL क्वेरी निष्पादित करना चाहते हैं:

using (var context = new DatabaseEntities())
{
    // delete existing records
    context.Database.ExecuteSqlCommand("DELETE FROM YOURTABLE WHERE CustomerID = @id", idParameter);
}

1
यह EF 5 में मेरे लिए काम करता है लेकिन मुझे परम के लिए @ p0 का उपयोग करना पड़ा। क्या अच्छा है कि यह जनरेट किए गए sql में टाइप सुरक्षित परम चेकिंग प्रदान करता है: इसलिए EF5 में, यह काम करेगा: संदर्भ। अगले पैराम, आदि के लिए \ @ p1 ...
नाथन प्रथम

3

RemoveRange को EF6 में पेश किया गया था, यह वस्तुओं की एक सूची को हटा सकता है। सुपर आसान है।

var origins= (from po in db.PermitOrigins where po.PermitID == thisPermit.PermitID select po).ToList();
db.PermitOrigins.RemoveRange(origins);
db.SaveChanges();

1
हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और वे लोग आपके कोड सुझाव के कारणों को नहीं जान सकते हैं।
दिमासन

2

मुझे किसी भी डेटा संदर्भ की DeleteAllOnSubmit विधि का पता है जो क्वेरी में सभी रिकॉर्ड हटा देगा। बहुत सारे ऑब्जेक्ट हटाए जाने के बाद से कुछ अनुकूलन अंतर्निहित होने चाहिए। हालांकि मुझे यकीन नहीं है।


3
वास्तव में कोई अनुकूलन प्रदर्शन नहीं किया जा रहा है। उत्पन्न SQL आपकी क्वेरी से मेल खाने वाली सभी वस्तुओं की गणना करता है, फिर उन्हें हटाने के लिए मैन्युअल रूप से उन पर पुनरावृत्ति करता है। दी गई, पुनरावृति आपके कोड के बजाय DB में होती है, लेकिन आप अभी भी इसकी सामग्री को हटाने के लिए केवल एक परिणाम सेट का निर्माण कर रहे हैं - फिर भी एक साधारण "DELETE FROM table WHERE foo = bar" से भी बदतर है, जो बनाता है कोई परिणाम नहीं सेट और केवल एक बार तालिका को कवर करता है।
बेंजामिन पोलाक

2

मुझे यकीन नहीं है कि यह कितना कुशल होगा, लेकिन आप कुछ इस तरह की कोशिश कर सकते हैं:

// deletes all "People" with the name "Joe"
var mypeople = from p in myDataContext.People
               where p.Name == "Joe";
               select p;
myDataContext.People.DeleteAllOnSubmit(mypeople);
myDataContext.SubmitChanges();

1
वह अभी भी क्वेरी से मेल खाने वाले सभी तत्वों पर निर्भर करता है; यह केवल आपके कोड के बजाय DB पर ऐसा करता है। अधिक कुशल, लेकिन अभी भी एक आदर्श समाधान से बहुत दूर है।
बेंजामिन पोलाक

3
एक और तरीका है कि मैं इसे करने के लिए सोच सकता था, फिर, myDataContext.ExecuteCommand ("DELETE ..."); आदर्श से दूर, भी, लेकिन यह काम करेगा।
स्कॉट एंडरसन

1

YO एक संग्रहित खरीद लिख सकता है जो डिलीट करता है और LINQ से कॉल करता है। एक सेट-आधारित हटाना समग्र रूप से तेज़ होने की संभावना है, लेकिन यदि यह बहुत सारे रिकॉर्ड को प्रभावित करता है तो आप लॉकिंग मुद्दों का कारण बन सकते हैं और आपको रिकॉर्ड के सेट के माध्यम से एक हाइब्रिड की आवश्यकता हो सकती है (शायद एक समय में 2000, आकार आपके डेटाबेस डिज़ाइन पर निर्भर करता है लेकिन 2000 एक है यदि आपको सेट-आधारित देरी मिल रही है, तो इसे शुरू करने के लिए जगह) तालिका के अन्य उपयोग को प्रभावित कर रही है।


1

एंटिटी फ्रेमवर्क के माध्यम से डेटा हटाना डिलीट ऑबजेक्ट पद्धति का उपयोग करने पर निर्भर करता है। आप जिस इकाई वर्ग को हटाना चाहते हैं उसके लिए EntityCollection पर या व्युत्पन्न ObjectContext पर इस विधि को कॉल कर सकते हैं। ये रहा एक सरल उदाहरण:

NorthwindEntities db = new NorthwindEntities();

IEnumerable<Order_Detail> ods = from o in db.Order_Details
                                where o.OrderID == 12345                                    
                                select o;

foreach (Order_Detail od in ods) 
    db.Order_Details.DeleteObject(od);

db.SaveChanges();

हालांकि यह "बल्क डिलीट" नहीं है।
nuzzolilo

1

इस उदाहरण में मुझे हटाने के लिए रिकॉर्ड मिलते हैं, और एक एक करके उन्हें परिणाम सेट पर संलग्न करते हैं, फिर उन्हें हटाने का अनुरोध करते हैं। तब मेरे पास 1 परिवर्तन सहेजे गए हैं।

    using (BillingDB db = new BillingDB())
    {
      var recordsToDelete = (from i in db.sales_order_item
                  where i.sales_order_id == shoppingCartId
                  select i).ToList<sales_order_item>();

      if(recordsToDelete.Count > 0)
      {
        foreach (var deleteSalesOrderItem in recordsToDelete)
        {                  
            db.sales_order_item.Attach(deleteSalesOrderItem);
            db.sales_order_item.Remove(deleteSalesOrderItem);                  
        }
        db.SaveChanges();
      } 
    }

1
 context.Entity.Where(p => p.col== id)
               .ToList().ForEach(p => db.Entity.DeleteObject(p));

ये EF का उपयोग करते हुए DB से रिकॉर्ड को हटाने की सबसे तेज़ विधि है


0

मैं कुछ करना चाहूँगा:

var recordsToDelete = (from c in db.Candidates_T where c.MyField == null select c).ToList<Candidates_T>();
if(recordsToDelete.Count > 0)
{
    foreach(var record in recordsToDelete)
    {
        db.Candidate_T.DeleteObject(record);
        db.SaveChanges();
    }
}   

मुझे नहीं लगता कि एंटिटी फ्रेमवर्क में एंटिटी के साथ काम करने के बाद से लूप के बिना ऐसा करने का एक तरीका है और ज्यादातर समय, इन वस्तुओं का संग्रह होता है।


आपने जो किया वह भी साझा कर सकते हैं। धन्यवाद।
जी जेनी रामिरेज़

@ जी जेनी रामिरेज़ ने मेरा समाधान जोड़ा।
Demodave

2
@ GJennyRamirez आपके उदाहरण में भी आप कई बार बचत कर रहे हैं, जो मुझे लगता है कि आप उस ओर की ओर लूप खींच सकते हैं और एक बार क्रियान्वित कर सकते हैं
Demodave
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.