2012-01-16 29 views
11

का उपयोग करके इकाई फ्रेमवर्क के साथ एकाधिक रिकॉर्ड हटाना मैं LINQ का उपयोग करके एक डेलेटी करने की कोशिश कर रहा हूं जो एक क्वेरी उत्पन्न करेगा।एक एकल LINQ क्वेरी

यहाँ कैसे मैं इसे कर रहा हूँ है:

// NorthwintEntities is an ADO.NET Entitity Data Model 
var northwindEntities = new NorthwindEntities(); 
northwindEntities.Order_Details.Delete(o => o.Order_ID == 11076); 

यहाँ मेरी एक्सटेंशन है:

public static class EntityExtensions 
{ 
    private static Regex rxTableName = new Regex(@"^FROM\s+(?<table>\[[^\]]*\](\.\[[^\]]*\]){0,2})\s+AS\s+(?<alias>\[[^\]]*\])", RegexOptions.Multiline); 

    public static void Delete<T>(this ObjectSet<T> entity, Expression<Func<T, bool>> expression) where T : EntityObject 
    { 
     var selectQuery = entity.Where(expression).Select(x => 1); 

     string selectQueryString = ((ObjectQuery)selectQuery).ToTraceString(); 

     string deleteQueryString = ConvertSqlSelectToDelete(selectQueryString); 

     entity.Context.ExecuteStoreCommand(deleteQueryString); 
    } 

    private static string ConvertSqlSelectToDelete(string selectQuery) 
    { 
     if (selectQuery.IndexOf(" JOIN ") > -1) 
     { 
      throw new Exception("Query with JOIN is not supported: " + selectQuery); 
     } 

     Match match = rxTableName.Match(selectQuery); 
     if (!match.Success) 
     { 
      throw new Exception("Unable to convert SELECT: " + selectQuery); 
     } 

     string deleteQuery = "DELETE \r\n" + selectQuery.Substring(match.Index); 
     deleteQuery = deleteQuery.Replace(match.Groups["alias"].Value + ".", ""); 
     deleteQuery = deleteQuery.Replace("AS " + match.Groups["alias"].Value, ""); 

     return deleteQuery; 
    } 
} 

यह काम करता है, लेकिन मैं कुछ टिप्पणी है।

  • मैं रेगेक्स का उपयोग करने का एक बड़ा प्रशंसक नहीं हूं, लेकिन यह टेबल नाम पाने का एकमात्र तरीका था। (entity.EntitySet.Name हमेशा सही नाम नहीं लौटाएगा। [ऑर्डर विवरण] एक उदाहरण है)।
  • इसे पूरा करने के बाद, मुझे यह http://msmvps.com/blogs/matthieu/archive/2010/05/21/bulk-delete-v3.aspx मिला लेकिन यह वैसे भी काम नहीं कर सका। संदर्भ से एक अप्रतिबंधित अपवाद प्राप्त करने के लिए हटा दिया गया है।
  • जॉइन के साथ हटाएं काम नहीं लग रहा है। मैं SQL सर्वर कॉम्पैक्ट 3.5 के साथ परीक्षण कर रहा हूं, शायद यह उस की एक सीमा है।

तो मेरे प्रश्न हैं: क्या ऐसा करने का कोई आसान तरीका है? यदि ऐसा है, तो ये क्या है?

किसी भी मदद बिल्कुल सराहना की जाएगी।

+4

के साथ ऑर्डर के अंदर सभी रिकॉर्ड कृपया [प्रश्न] [1] पर एक नज़र डालें। [1]: http://stackoverflow.com/questions/8538899/ –

+0

क्या आपने EF6 में RemoveRange माना है? मैं जानना चाहता हूं कि यह "अनुकूलित" कितना है और यह किस प्रकार चलता है। http://msdn.microsoft.com/en-us/library/system.data.entity.dbset.removerange(v=vs.113).aspx – Colin

+0

मेटाडेटा से तालिका का नाम प्राप्त करना - http://stackoverflow.com/a/18 9 64 9 74/150342 – Colin

उत्तर

8
  1. स्थापित इकाई की रूपरेखा विस्तारित लाइब्रेरी (प्रधानमंत्री> इंस्टॉल करें-पैकेज EntityFramework.Extended) अपने कोड में

  2. आयात EntityFramework.Extensions

  3. हटाएं रिकॉर्ड भीतरी क्वेरी द्वारा निर्दिष्ट

    context.Orders.Where(o=>o.User_ID == 1).Delete(); 
    

हटाएं उपयोगकर्ता आईडी = 1

+0

यह एंटीटीफ्रेमवर्क की भावना में एक विशिष्ट प्रदाता (एसक्यूएल-सर्वर) तक सीमित नहीं है। – springy76

5

बैच हटाने का एक तरीका विदेशी कुंजी पर कैस्केड डिलीट पर सेट कर रहा है। आपको डिज़ाइनर में संबंधों पर कैस्केड सेट करना होगा और डेटाबेस में संबंधों पर कैस्केड डिलीट पर सेट करना होगा।

ऑर्डर ईएफ से उत्पाद नेविगेशन संपत्ति को हटाने के लिए (उत्पाद गुणों की संख्या) डेटाबेस में +1 कथन करेगा।

मैं इसे करना पसंद:

var order = context.Orders.Include(p=>p.Products).Where(o=>o.Order_ID == 11076); 

foreach(Product product in order.Products.ToList()) 
{ 
    context.Entry(product).State = EntityState.Deleted; 
} 
context.Entry(order).State = EntityState.Deleted; 
context.SaveChanges(); 

आशा है कि यह मदद करता है।

+3

गणित में अगले आइटम के लिए आगे बढ़ने पर, यह त्रुटि के साथ आता है "आइटम सूची से संशोधित, गणना के लिए आगे बढ़ नहीं सकता है। – DOM

+0

यह एंटिटी v5 –

+0

में काम नहीं करता है, मुझे नहीं पता कि @DOM का कहना है कि यह काम नहीं करता है। यह पूरी तरह से ठीक काम करता है बशर्ते आप ToList() विधि को कॉल करना न भूलें। – NoobDeveloper