मैं एंटिटी फ्रेमवर्क में कई पंक्तियों को कैसे हटा सकता हूं (बिना फॉरचेक के)


305

मैं एंटिटी फ्रेमवर्क का उपयोग करके एक टेबल से कई आइटम हटा रहा हूं। कोई विदेशी कुंजी / पैरेंट ऑब्जेक्ट नहीं है, इसलिए मैं इसे OnDeleteCascade के साथ संभाल नहीं सकता।

अभी मैं यह कर रहा हूँ:

var widgets = context.Widgets
    .Where(w => w.WidgetId == widgetId);

foreach (Widget widget in widgets)
{
    context.Widgets.DeleteObject(widget);
}
context.SaveChanges();

यह काम करता है लेकिन foreach मुझे परेशान करता है। मैं EF4 का उपयोग कर रहा हूं, लेकिन मैं SQL निष्पादित नहीं करना चाहता। मैं बस यह सुनिश्चित करना चाहता हूं कि मुझे कुछ भी याद नहीं है - यह उतना ही अच्छा है जितना कि यह सही है? मैं इसे एक विस्तार विधि या सहायक के साथ अमूर्त कर सकता हूं, लेकिन कहीं हम अभी भी एक फॉर्च्यूनर के लिए जा रहे हैं, है ना?


1
आप स्वीकृत उत्तर पर फिर से विचार करना चाहते हैं।
एरिक जे।

1
यदि आप प्रदर्शनकारी बने रहना चाहते हैं, तो आप मेरे जवाब को यहां पर देख सकते हैं। stackoverflow.com/a/35033286/274589
Adi

जवाबों:


49

यदि आप SQL को सीधे निष्पादित नहीं करना चाहते हैं तो DeleteObject को एक लूप में कॉल करना सबसे अच्छा है जो आप आज कर सकते हैं।

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

हालांकि वह जवाब 3.5 का था। 4.0 के लिए, मैं शायद StoreConnection को छोड़ने के बजाय हुड के तहत नए ExecuteStoreCommand API का उपयोग करूंगा।


ExecuteStoreCommand एक उचित तरीका नहीं है ।eleteAllSubmit linq में sql पर काम कर रही है, लेकिन इकाई ढांचे में नहीं। मैं इकाई ढांचे में एक ही विकल्प चाहता हूं।
हीरल

653

EntityFramework 6 ने इसे थोड़ा आसान बना दिया है .RemoveRange()

उदाहरण:

db.People.RemoveRange(db.People.Where(x => x.State == "CA"));
db.SaveChanges();

31
यह ठीक वैसा ही है, जिसकी हमें जरूरत है ... जब मैं इसे एक बड़ी सीमा पर उपयोग करता हूं, तो मुझे एक मेमोरी-आउट अपवाद मिल जाता है! मुझे लगा कि RemoveRange का पूरा बिंदु प्रसंस्करण को डेटाबेस में पारित करना था, लेकिन स्पष्ट रूप से नहीं।
समीर आद्रा

यह हर इकाई को हटाए गए राज्य को सेट करने से अधिक तेज़ है!
जेरथ

54
यह सुनिश्चित करने के लिए कि यह उत्तर आसान है, लेकिन प्रदर्शन के लिहाज से यह बहुत अच्छा नहीं है। क्यों? यह बाहरी डाइट, फॉर्चर लूप में इसे हटाने के समान है, यह पहले सभी पंक्तियों को प्राप्त करता है और फिर एक-एक करके डिलीट होता है, केवल लाभ के लिए है "DetectChanges किसी भी संस्थाओं को हटाने से पहले एक बार कॉल किया जाएगा और फिर से कॉल नहीं किया जाएगा" बाकी एक ही है, sql उत्पन्न देखने के लिए उपकरण का उपयोग करने का प्रयास करें।
अंशुल निगम

6
एक बड़ी पर्याप्त सीमा के लिए, कुछ को आज़माएँ। जैसे (10000) निकालें और रिमरेंज (...) तक गिनें। गिनती () == 0.
एरिक जे।

20
समस्या यह है कि RemoveRange इनपुट पैरामीटर एक IEnumerable है, इसलिए इसे हटाने के लिए सभी संस्थाओं को एन्यूमरेट करता है और प्रति इकाई 1 DELETE क्वेरी चलाता है।
बुबी

74

यह उतना ही अच्छा है जितना यह सही है? मैं इसे एक विस्तार विधि या सहायक के साथ अमूर्त कर सकता हूं, लेकिन कहीं हम अभी भी एक फॉर्च्यूनर के लिए जा रहे हैं, है ना?

ठीक है, हाँ, सिवाय इसके कि आप इसे दो-लाइनर में बना सकते हैं:

context.Widgets.Where(w => w.WidgetId == widgetId)
               .ToList().ForEach(context.Widgets.DeleteObject);
context.SaveChanges();

76
आप एक ToList () कर रहे हैं जो उद्देश्य को हराता है। मूल समाधान से यह कैसे अलग है?
लहस्रा

3
मेरे पास समस्याएँ हैं क्योंकि मेरे पास केवल संदर्भ ऑब्जेक्ट में विधि निकालें।
Pnct

2
यह निश्चित रूप से एक उपयुक्त समाधान नहीं है जब एक लाख पंक्तियों (या यहां तक ​​कि कुछ सौ) की उम्मीद की जाती है। हालाँकि, अगर हम निश्चित रूप से जानते हैं कि कुछ ही पंक्तियाँ होंगी, यह समाधान साफ-सुथरा है और पूरी तरह से काम करता है। हां, इसमें DB के लिए कुछ गोल यात्राएं शामिल होंगी, लेकिन मेरी राय में SQL को कॉल करने में खोए हुए अमूर्त लाभ को सीधे तौर पर लाभ मिलता है।
योगस्टर

इकाई ढांचा, जैसा कि नाम से पता चलता है, इकाई स्तर पर डेटा के साथ सबसे अच्छा काम करता है। बल्क डेटा ऑपरेशंस अच्छे पुराने संग्रहित प्रोक्स द्वारा सबसे अच्छे रूप में संभाले जाते हैं। प्रदर्शन-वार वे अब तक के सबसे अच्छे विकल्प हैं और लूप की आवश्यकता वाले किसी भी ईएफ तर्क को हरा देंगे।
पेसमैन

72
using (var context = new DatabaseEntities())
{
    context.ExecuteStoreCommand("DELETE FROM YOURTABLE WHERE CustomerID = {0}", customerId);
}

लेकिन आप आईडी की सूची के साथ ऐसा कैसे कर सकते हैं? यह समाधान "सूचियों" को बहुत अच्छी तरह से संभाल नहीं करता है।
जेसी न्यूमैन 19

11
@ JesseNewman19 यदि आपके पास पहले से ही आईडी की एक सूची है WHERE IN ({0}), तो एक का उपयोग करें , और फिर दूसरा तर्क होना चाहिए String.Join(",", idList)
लैंगडन

@ लैंगडन जो काम नहीं करेगा, क्योंकि यह कमांड को sql की तरह भेजेगा: WHERE IN ("1, 2, 3")। डेटाबेस तब एक त्रुटि फेंकता है क्योंकि आपने इसे पूर्णांक की सूची के बजाय एक स्ट्रिंग पास किया था।
जेसी नेवमान 19

मैं LINQ के साथ ऐसा स्टेटमेंट जेनरेट करना चाहता हूं। सबसे करीबी चीज जो मुझे मिली, वह एक परिवाद था। EntityFramework.Extended
जैदर

यदि आप उपयोग कर रहे हैं String.Join, तो आपको string.Formatकमांड के लिए पहले से गठित SQL स्ट्रिंग का उपयोग और पास करने की आवश्यकता हो सकती है । जब तक आपकी सूची में केवल पूर्णांक हैं, तब तक इंजेक्शन के हमले का खतरा नहीं है। इस प्रश्न की जाँच करें: मैं किसी सरणी को निष्पादित स्टोर कमांड में कैसे पास कर सकता हूं?
एंड्रयू

50

मुझे पता है कि यह काफी देर हो चुकी है, लेकिन अगर किसी को एक सरल समाधान की आवश्यकता है, तो ठंडी बात यह है कि आप इसके साथ जहां खंड जोड़ सकते हैं:

public static void DeleteWhere<T>(this DbContext db, Expression<Func<T, bool>> filter) where T : class
{
    string selectSql = db.Set<T>().Where(filter).ToString();
    string fromWhere = selectSql.Substring(selectSql.IndexOf("FROM"));
    string deleteSql = "DELETE [Extent1] " + fromWhere;
    db.Database.ExecuteSqlCommand(deleteSql);
}

नोट: सिर्फ MSSQL2008 के साथ परीक्षण किया गया।

अपडेट करें:

जब EF पैरामीटर के साथ sql स्टेटमेंट तैयार करता है , तो उपरोक्त समाधान काम नहीं करेगा , इसलिए यहां EF5 के लिए अपडेट है :

public static void DeleteWhere<T>(this DbContext db, Expression<Func<T, bool>> filter) where T : class
{
    var query = db.Set<T>().Where(filter);

    string selectSql = query.ToString();
    string deleteSql = "DELETE [Extent1] " + selectSql.Substring(selectSql.IndexOf("FROM"));

    var internalQuery = query.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(field => field.Name == "_internalQuery").Select(field => field.GetValue(query)).First();
    var objectQuery = internalQuery.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(field => field.Name == "_objectQuery").Select(field => field.GetValue(internalQuery)).First() as ObjectQuery;
    var parameters = objectQuery.Parameters.Select(p => new SqlParameter(p.Name, p.Value)).ToArray();

    db.Database.ExecuteSqlCommand(deleteSql, parameters);
}

इसके लिए थोड़े से प्रतिबिंब की आवश्यकता होती है लेकिन यह अच्छी तरह से काम करता है।


DbContext क्या है? मैं आपके ऑटो-जनरेट किए गए इकाई ढांचे के संदर्भ को मानता हूं? मेरे पास सेट <T> नामक विधि नहीं है।
चुपके रब्बी

@Stealth: हाँ, यह आपका EF डेटा संदर्भ है, मैं कोड-प्रथम का उपयोग करता हूं, लेकिन ऑटो-जनरेटेड संदर्भ समान होना चाहिए। गलत टाइप किए गए बयान के लिए क्षमा करें, इसे सेट होना चाहिए <T> () (मेरी कंपनी इंटरनेट एक्सेस को रोकती है जिसे मैं कोड पेस्ट नहीं कर सकता, उसे हाथ से टाइप करना था ...), कोड अपडेट किए गए :)
थान नगुयेन

3
यह एकमात्र उत्तर है जो वास्तव में प्रश्न का उत्तर देता है! हर दूसरे जवाब में एक बार में प्रत्येक व्यक्ति के आइटम को हटा दिया जाता है, अविश्वसनीय।
रॉकलान

यह सबसे सही उत्तर की तरह लगता है। यह बहुत ही सामान्य तरीके से विलोपन की अनुमति देता है, और यह डेटाबेस में काम को सही ढंग से बंद कर देता है न कि सी #।
जेसनमैन 19

1
वहाँ बाहर सभी कम तकनीकी प्रोग्रामर के लिए, मैं इस उत्कृष्ट और सामान्य समाधान को लागू करने के बारे में थोड़ा और विस्तार करना चाहता था, क्योंकि इससे मुझे कुछ मिनटों का समय बचा होता था! अगली टिप्पणी में जारी ...
jdnew18

30

EF5 का उपयोग करने वाले किसी भी व्यक्ति के लिए, विस्तार लाइब्रेरी का उपयोग किया जा सकता है: https://github.com/loresoft/EntityFramework.Efended

context.Widgets.Delete(w => w.WidgetId == widgetId);

3
बड़ी तालिकाओं पर प्रदर्शन की समस्या है, मेरी स्थिति में उपयोग करने योग्य नहीं है।
टॉमस

@ टॉमास ने किस तरह का परफॉमेंस जारी किया? मुद्दा कितना गंभीर था और मेज पर कितनी बड़ी थी? कोई और इसकी पुष्टि कर सकता है?
एनेस्टिस किवरनग्लू

यह वास्तव में तेजी से वहाँ से बाहर के विकल्पों की तुलना में है
Jaider

मैं Delete()EF6 में अपनी संस्थाओं में कार्य नहीं देख सकता ।
डॉटनेट

context.Widgets.Where(w => w.WidgetId == widgetId).Delete();EntityFramework.Extended
पीटर केर

11

अभी भी कुछ भी करने के लिए सर्वर से कुछ भी वापस खींचने के लिए पागल हो रहा है, लेकिन कम से कम सिर्फ आईडी प्राप्त करना पूर्ण संस्थाओं को नीचे खींचने की तुलना में बहुत अधिक झुकाव है:

var ids = from w in context.Widgets where w.WidgetId == widgetId select w.Id;
context.Widgets.RemoveRange(from id in ids.AsEnumerable() select new Widget { Id = id });

सावधान रहें - यह एंटिटी फ्रेमवर्क की इकाई सत्यापन को विफल कर सकता है क्योंकि आपके स्टब Widgetऑब्जेक्ट्स में केवल एक प्रारंभिक Idसंपत्ति होती है। इसका उपयोग करने का तरीका context.Configuration.ValidateOnSaveEnabled = false(कम से कम EF6 में) है। यह एंटिटी फ्रेमवर्क की अपनी मान्यता को अक्षम कर देता है, लेकिन फिर भी डेटाबेस की अपनी मान्यता को पूरा करता है।
सैमी एस

@SammyS। मैंने ऐसा अनुभव नहीं किया है, इसलिए विवरण पर बात नहीं कर सकता, लेकिन यह अजीब लगता है कि ईएफ सत्यापन के साथ परेशान करेगा जब यह वैसे भी पंक्ति को हटा रहा है।
एडवर्ड ब्रे

आप बिल्कुल सही हैं। मैं उन्हें लोड किए बिना संस्थाओं के deleteलिए एक समान समाधान के साथ उलझन में updateहूं।
सैमी एस

10

ईएफ 6.1

public void DeleteWhere<TEntity>(Expression<Func<TEntity, bool>> predicate = null) 
where TEntity : class
{
    var dbSet = context.Set<TEntity>();
    if (predicate != null)
        dbSet.RemoveRange(dbSet.Where(predicate));
    else
        dbSet.RemoveRange(dbSet);

    context.SaveChanges();
} 

उपयोग:

// Delete where condition is met.
DeleteWhere<MyEntity>(d => d.Name == "Something");

Or:

// delete all from entity
DeleteWhere<MyEntity>();

7
यह प्रभावी रूप से db.People.RemoveRange (db.People.Where (x => x.State == "CA")) के समान है; db.SaveChanges (); तो कोई प्रदर्शन लाभ नहीं।
रीनियरडॉग

4

EF 4.1 के लिए,

var objectContext = (myEntities as IObjectContextAdapter).ObjectContext;
objectContext.ExecuteStoreCommand("delete from [myTable];");

1
यह काम करता है, लेकिन एंटिटी फ्रेमवर्क का उपयोग करने के पूरे बिंदु में डेटाबेस के साथ बातचीत करने के लिए एक वस्तु-उन्मुख तरीका है। यह सीधे SQL क्वेरी चला रहा है।
आर्टुरो टॉरेस सैंचेज़

4

आप EntityFramework.Extended या Z.EntityFramework.Plus.EF6 जैसे एक्सटेंशन लाइब्रेरी का उपयोग कर सकते हैं, EF 5, 6 या कोर के लिए उपलब्ध हैं। जब आपको हटाना या अपडेट करना होता है, तो इन पुस्तकालयों का बहुत अच्छा प्रदर्शन होता है और वे LINQ का उपयोग करते हैं। हटाने के लिए उदाहरण ( स्रोत प्लस ):

ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) .Delete();

या ( स्रोत बढ़ाया गया )

context.Users.Where(u => u.FirstName == "firstname") .Delete();

ये मूल SQL स्टेटमेंट का उपयोग करते हैं, इसलिए प्रदर्शन बहुत अच्छा है।


थोक sql ऑपरेशन जनरेटर के लिए 600 $ + का भुगतान करें। गंभीरता से?
निकोले.न्यकीन्को

@ nicolay.anykienko जब मैंने इसका इस्तेमाल किया, तो यह लाइब्रेरी मुफ़्त थी, ऐसे अन्य ऑपरेशन हैं जहां आपको भुगतान करना होगा, ठीक है मुझे नहीं पता कि आपको भुगतान करना है
UUHHIVS

3

हटाने का सबसे तेज़ तरीका एक संग्रहीत प्रक्रिया का उपयोग करना है। मैं गतिशील SQL पर डेटाबेस प्रोजेक्ट में संग्रहीत कार्यविधियों को प्राथमिकता देता हूं क्योंकि नाम सही ढंग से संभाले जाएंगे और संकलक त्रुटियां होंगी। डायनामिक एसक्यूएल उन तालिकाओं को संदर्भित कर सकता है जिन्हें हटा दिया गया है / नाम बदला गया है जो रन टाइम त्रुटियां हैं।

इस उदाहरण में, मेरे पास दो टेबल सूची और सूचियाँ हैं। मुझे दिए गए सूची के सभी ListItems को हटाने के लिए एक तेज़ तरीके की आवश्यकता है।

CREATE TABLE [act].[Lists]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [Name] NVARCHAR(50) NOT NULL
)
GO
CREATE UNIQUE INDEX [IU_Name] ON [act].[Lists] ([Name])
GO
CREATE TABLE [act].[ListItems]
(
    [Id] INT NOT NULL IDENTITY, 
    [ListId] INT NOT NULL, 
    [Item] NVARCHAR(100) NOT NULL, 
    CONSTRAINT PK_ListItems_Id PRIMARY KEY NONCLUSTERED (Id),
    CONSTRAINT [FK_ListItems_Lists] FOREIGN KEY ([ListId]) REFERENCES [act].[Lists]([Id]) ON DELETE CASCADE
)
go
CREATE UNIQUE CLUSTERED INDEX IX_ListItems_Item 
ON [act].[ListItems] ([ListId], [Item]); 
GO

CREATE PROCEDURE [act].[DeleteAllItemsInList]
    @listId int
AS
    DELETE FROM act.ListItems where ListId = @listId
RETURN 0

अब आइटमों को हटाने और एक्सटेंशन का उपयोग करके एंटिटी ढांचे को अपडेट करने का दिलचस्प हिस्सा।

public static class ListExtension
{
    public static void DeleteAllListItems(this List list, ActDbContext db)
    {
        if (list.Id > 0)
        {
            var listIdParameter = new SqlParameter("ListId", list.Id);
            db.Database.ExecuteSqlCommand("[act].[DeleteAllItemsInList] @ListId", listIdParameter);
        }
        foreach (var listItem in list.ListItems.ToList())
        {
            db.Entry(listItem).State = EntityState.Detached;
        }
    }
}

मुख्य कोड अब इसका उपयोग कर सकता है

[TestMethod]
public void DeleteAllItemsInListAfterSavingToDatabase()
{
    using (var db = new ActDbContext())
    {
        var listName = "TestList";
        // Clean up
        var listInDb = db.Lists.Where(r => r.Name == listName).FirstOrDefault();
        if (listInDb != null)
        {
            db.Lists.Remove(listInDb);
            db.SaveChanges();
        }

        // Test
        var list = new List() { Name = listName };
        list.ListItems.Add(new ListItem() { Item = "Item 1" });
        list.ListItems.Add(new ListItem() { Item = "Item 2" });
        db.Lists.Add(list);
        db.SaveChanges();
        listInDb = db.Lists.Find(list.Id);
        Assert.AreEqual(2, list.ListItems.Count);
        list.DeleteAllListItems(db);
        db.SaveChanges();
        listInDb = db.Lists.Find(list.Id);
        Assert.AreEqual(0, list.ListItems.Count);
    }
}

संग्रहित प्रक्रिया का उपयोग करने के एक अच्छे उदाहरण के लिए धन्यवाद, और फिर उपयोग कोड के साथ इसे विस्तार के रूप में लागू करना।
ग्लेन गार्सन

3

यदि आप किसी तालिका की सभी पंक्तियों को हटाना चाहते हैं, तो आप sql कमांड निष्पादित कर सकते हैं

using (var context = new DataDb())
{
     context.Database.ExecuteSqlCommand("TRUNCATE TABLE [TableName]");
}

TRUNCATE TABLE (Transact-SQL) अलग-अलग पंक्ति विलोपन को लॉग किए बिना किसी तालिका से सभी पंक्तियों को निकालता है। TRUNCATE टेबल DELETE स्टेटमेंट के समान है जिसमें कोई क्लॉज नहीं है; हालाँकि, TRUNCATE TABLE तेज़ है और कम सिस्टम और लेनदेन लॉग संसाधनों का उपयोग करता है।


3
आपको यह भी उल्लेख करना चाहिए कि आप उन truncate tableतालिकाओं पर नहीं चल सकते हैं जो एक पूर्व प्रमुख बाधा द्वारा संदर्भित हैं। (आप एक तालिका को काट सकते हैं जिसमें एक विदेशी कुंजी है जो खुद को संदर्भित करता है।) MSDN प्रलेखन
ब्रॉडबैंड

2

UUHHIVSबैच हटाने के लिए एक बहुत ही सुंदर और तेज़ तरीका है, लेकिन इसका उपयोग सावधानी से किया जाना चाहिए:

  • लेन-देन की ऑटो पीढ़ी: इसके प्रश्नों को लेनदेन द्वारा शामिल किया जाएगा
  • डेटाबेस संदर्भ स्वतंत्रता: इसके निष्पादन का कोई लेना-देना नहीं है context.SaveChanges()

लेन-देन पर नियंत्रण करके इन मुद्दों को दरकिनार किया जा सकता है। निम्न कोड दिखाता है कि कैसे बैच डिलीट और बल्क इंसर्ट को ट्रांसेक्शनल तरीके से किया जाता है:

var repo = DataAccess.EntityRepository;
var existingData = repo.All.Where(x => x.ParentId == parentId);  

TransactionScope scope = null;
try
{
    // this starts the outer transaction 
    using (scope = new TransactionScope(TransactionScopeOption.Required))
    {
        // this starts and commits an inner transaction
        existingData.Delete();

        // var toInsert = ... 

        // this relies on EntityFramework.BulkInsert library
        repo.BulkInsert(toInsert);

        // any other context changes can be performed

        // this starts and commit an inner transaction
        DataAccess.SaveChanges();

        // this commit the outer transaction
        scope.Complete();
    }
}
catch (Exception exc)
{
    // this also rollbacks any pending transactions
    scope?.Dispose();
}

2

इकाई फ्रेमवर्क कोर

3.1 3.0 2.2 2.1 2.0 1.1 1.0

using (YourContext context = new YourContext ())
{
    var widgets = context.Widgets.Where(w => w.WidgetId == widgetId);
    context.Widgets.RemoveRange(widgets);
    context.SaveChanges();
}

सारांश :

निकाले गए राज्य में डाले गए प्रत्येक इकाई के साथ सेट से जुड़े संदर्भ से संस्थाओं के दिए गए संग्रह को हटाता है, जैसे कि जब SaveChanges कहा जाता है, तो इसे डेटाबेस से हटा दिया जाएगा।

टिप्पणी :

ध्यान दें कि यदि System.Data.Entity.Infrastructure.DbContextConfiguration.AutoDetectChangesEnabled सही पर सेट है (जो डिफ़ॉल्ट है), तो DetectChanges को किसी भी संस्था को हटाने से पहले कॉल किया जाएगा और फिर से कॉल नहीं किया जाएगा। इसका मतलब यह है कि कुछ स्थितियों में RemoveRange कई बार कॉल हटाने से बेहतर प्रदर्शन कर सकता है। ध्यान दें कि यदि कोई भी इकाई जोड़ा राज्य में संदर्भ में मौजूद है, तो यह विधि इस संदर्भ से अलग हो जाएगी। ऐसा इसलिए है क्योंकि एक जोड़ा निकाय को डेटाबेस में मौजूद नहीं माना जाता है जैसे कि इसे हटाने की कोशिश करने का कोई मतलब नहीं है।


1

आप निम्नानुसार सीधे एसक्यूएल प्रश्नों को निष्पादित कर सकते हैं:

    private int DeleteData()
{
    using (var ctx = new MyEntities(this.ConnectionString))
    {
        if (ctx != null)
        {

            //Delete command
            return ctx.ExecuteStoreCommand("DELETE FROM ALARM WHERE AlarmID > 100");

        }
    }
    return 0;
}

चयन के लिए हम उपयोग कर सकते हैं

using (var context = new MyContext()) 
{ 
    var blogs = context.MyTable.SqlQuery("SELECT * FROM dbo.MyTable").ToList(); 
}

यह देखते हुए कि EF डिलीट की गई शर्तों की मैपिंग का ठीक से समर्थन नहीं करता है, यह संभवतः काम पाने के लिए आपका सबसे अच्छा दांव है।
टोनी ओ'हागन

1

आप DeleteAllOnSubmit () मेथड को var के बजाए एक जेनेरिक लिस्ट में डालकर उसका उपयोग कर सकते हैं । इस तरह से आपका फोरच्यू कोड की एक पंक्ति तक कम हो जाता है:

List<Widgets> widgetList = context.Widgets
              .Where(w => w.WidgetId == widgetId).ToList<Widgets>();

context.Widgets.DeleteAllOnSubmit(widgetList);

context.SubmitChanges();

यह शायद अभी भी आंतरिक रूप से एक लूप का उपयोग करता है।


3
लगता है कि आप गलत समझ रहे हैं कि क्या varहै।
स्वतंत्रता-

1

थान के जवाब ने मेरे लिए सबसे अच्छा काम किया। एक एकल सर्वर यात्रा में मेरे सारे रिकॉर्ड हटा दिए गए। मैं वास्तव में एक्सटेंशन पद्धति को कॉल करने के लिए संघर्ष कर रहा था, इसलिए सोचा कि मैं अपना (ईएफ 6) साझा करूंगा:

मैंने अपने MVC प्रोजेक्ट में एक सहायक वर्ग के लिए एक्सटेंशन विधि को जोड़ा और नाम को "RemoveWhere" में बदल दिया। मैं अपने नियंत्रकों में एक dbContext इंजेक्ट करता हूं, लेकिन आप भी कर सकते हैं using

// make a list of items to delete or just use conditionals against fields
var idsToFilter = dbContext.Products
    .Where(p => p.IsExpired)
    .Select(p => p.ProductId)
    .ToList();

// build the expression
Expression<Func<Product, bool>> deleteList = 
    (a) => idsToFilter.Contains(a.ProductId);

// Run the extension method (make sure you have `using namespace` at the top)
dbContext.RemoveWhere(deleteList);

इसने समूह के लिए एकल डिलीट स्टेटमेंट उत्पन्न किया।


0

EF 6। =>

var assignmentAddedContent = dbHazirBot.tbl_AssignmentAddedContent.Where(a =>
a.HazirBot_CategoryAssignmentID == categoryAssignment.HazirBot_CategoryAssignmentID);
dbHazirBot.tbl_AssignmentAddedContent.RemoveRange(assignmentAddedContent);
dbHazirBot.SaveChanges();

0

श्रेष्ठ : in EF6 => .RemoveRange()

उदाहरण:

db.Table.RemoveRange(db.Table.Where(x => Field == "Something"));

14
यह काइल के उत्तर से कैसे अलग है?

-1

उत्तर 'पसंदीदा बिट ऑफ़ कोड' देखें जो काम करता है

यहाँ है कि मैं इसे कैसे इस्तेमाल किया:

     // Delete all rows from the WebLog table via the EF database context object
    // using a where clause that returns an IEnumerable typed list WebLog class 
    public IEnumerable<WebLog> DeleteAllWebLogEntries()
    {
        IEnumerable<WebLog> myEntities = context.WebLog.Where(e => e.WebLog_ID > 0);
        context.WebLog.RemoveRange(myEntities);
        context.SaveChanges();

        return myEntities;
    }

1
आपका उत्तर user1308743 उत्तर से कैसे भिन्न है ?
सर्गेई बेरेज़ोवस्की

मैं बस एक काम का उदाहरण साझा कर रहा था। जो भी मदद मुझे यहां मिल रही है उसे वापस देने के लिए मैं जो कुछ भी कर सकता हूं।
ब्रायन क्विन

-3

EF 6.2 में यह पूरी तरह से काम करता है, पहले डेटाबेस को लोड किए बिना डेटाबेस में सीधे डिलीट भेजना:

context.Widgets.Where(predicate).Delete();

एक निश्चित विधेय के साथ यह काफी सीधा है:

context.Widgets.Where(w => w.WidgetId == widgetId).Delete();

और अगर आपको एक गतिशील विधेय की आवश्यकता है, तो LINQKit (Nuget पैकेज उपलब्ध) पर एक नज़र है , ऐसा कुछ मेरे मामले में ठीक काम करता है:

Expression<Func<Widget, bool>> predicate = PredicateBuilder.New<Widget>(x => x.UserID == userID);
if (somePropertyValue != null)
{
    predicate = predicate.And(w => w.SomeProperty == somePropertyValue);
}
context.Widgets.Where(predicate).Delete();

1
कच्चे ईएफ 6.2 के साथ यह संभव नहीं है। शायद आप Z.EntityFramework.Plusया कुछ इसी तरह का उपयोग कर रहे हैं ? ( unitframework.net/batch-delete )
सैमी एस

पहला कच्चा EF 6.2 है और काम करता है। दूसरा एक है, जैसा कि मैंने उल्लेख किया है, LINQKit का उपयोग करते हुए।
व्लादिमीर

1
हम्म, मैं यह तरीका नहीं खोज सकता। क्या आप जाँच कर सकते हैं कि किस वर्ग और किस नामस्थान पर यह पद्धति निवास करती है?
सैमी एस

मैं तीसरा ( Delete()विधि स्वाभाविक रूप से अस्तित्वहीन है)।
सम कोई नहीं
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.