इकाई फ्रेमवर्क से एक भी रिकॉर्ड हटाएं?


195

मेरे पास एंटिटी फ्रेमवर्क में एक SQL सर्वर टेबल है जिसका नाम employएकल कुंजी कॉलम है ID

मैं एंटिटी फ्रेमवर्क का उपयोग करके तालिका से एक एकल रिकॉर्ड कैसे हटा सकता हूं?


2
db.employ.Remove (db.employ.Find (ID1))
कार्टर मेडलिन

2
@CarterMedlin - जबकि वह काम करेगा, वे दो डेटाबेस हिट हैं: एक का चयन और एक DELETE। ज्यादातर लोगों को लगता है कि बेहद बेकार है, खासकर जब से चयन शायद एक नष्ट करने की तुलना में काफी अधिक समय लगेगा।
डावोर

मैं प्रदर्शन के मुद्दों के कारण इकाई ढांचे निकालें या RemoveRange का उपयोग करने का सुझाव नहीं दूंगा। मैं केवल निम्नलिखित के रूप में कुछ सुपर सरल का उपयोग करूँगा: var sql = "DELETE FROM YOUR_TABLE WHERE YOUR_FIELD = @your_parameter"; this.your_context.Database.ExecuteSqlCommand (sql, new SqlParameter ("@ your_parameter", yourParameter));
जिज्ञासु बोय

2
@ CuriousBoy मुझे लगता है कि जब आप अपने सुझाए गए कथनों को निष्पादित करते हैं, तो EF6 कैश परिवर्तन को प्रतिबिंबित नहीं करता है।
यिट्ज़चाक

जवाबों:


362

पहले ऑब्जेक्ट को क्वेरी करना आवश्यक नहीं है, आप इसे अपनी आईडी द्वारा संदर्भ में संलग्न कर सकते हैं। ऐशे ही:

var employer = new Employ { Id = 1 };
ctx.Employ.Attach(employer);
ctx.Employ.Remove(employer);
ctx.SaveChanges();

वैकल्पिक रूप से, आप हटाए गए प्रविष्टि की स्थिति को हटा सकते हैं:

var employer = new Employ { Id = 1 };
ctx.Entry(employer).State = EntityState.Deleted;
ctx.SaveChanges();

87
वैकल्पिक रूप से,ctx.Entry(employer).State = EntityState.Deleted
साइमन बेलांगर

12
यह तभी काम करेगा जब रिश्तों को डिलीट कैस्केड के रूप में परिभाषित किया जाएगा। अन्यथा उपरोक्त कोड FK अपवाद पर विफल हो जाएगा।
बारूच

6
@ mt_serg, मैं 3 कदम आगे देख रहा हूँ। जब आखिरी बार आपको वास्तव में डीबी से इस तरह के एक सरल रिकॉर्ड को हटाना पड़ा था? आमतौर पर आप अधिक जटिल रिकॉर्डों के साथ काम कर रहे होते हैं जिनमें एफके संबंध शामिल होते हैं। इसलिए मेरी टिप्पणी।
बारूच

2
@ इयानवर्बटन द 2nd और 3rd लाइन (अटैच एंड निकालें)
साइमन

4
@PaZZahra: कभी-कभी आपके पास किसी अन्य क्वेरी या स्रोत से आईडी की एक सूची होती है, और आपको एक को हटाने की आवश्यकता होती है। वस्तुओं को केवल उन्हें हटाने के लिए लोड करने के बजाय, इस तरह आप आईडी द्वारा हटा सकते हैं। आप जानते हैं, कि SQL में DELETE स्टेटमेंट सामान्य रूप से कैसे काम करता है।
१।

82

आप SingleOrDefaultअपने मापदंड से मेल खाते एक एकल ऑब्जेक्ट प्राप्त करने के लिए उपयोग कर सकते हैं , और फिर उसे Removeअपने ईएफ तालिका की विधि में पास कर सकते हैं।

var itemToRemove = Context.Employ.SingleOrDefault(x => x.id == 1); //returns a single item.

if (itemToRemove != null) {
    Context.Employ.Remove(itemToRemove);
    Context.SaveChanges();
}

5
यह अच्छा तरीका नहीं है, क्योंकि आप डेटाबेस से सभी क्षेत्र चुन रहे हैं!
अली यूसेफी

2
इस तरह से मैं यह कर रहा हूँ।
जैक फेयरफील्ड

4
@ अली, जैक - लेकिन मुझे लगता है कि यह बेहतर है क्योंकि यह पहली बार जांचता है कि क्या आप जिस डेटा को हटाने की कोशिश कर रहे हैं वह वास्तव में मौजूद है जो किसी भी परेशानी को रोक सकता है। स्वीकृत उत्तर की कोई जांच नहीं है।
माइकल फिलिप्स

4
यह बेहतर तरीका है। इसके बारे में सोचो। क्या होगा यदि जॉन स्मिथ एक आईडी = 1 के साथ एक आइटम को हटाने की कोशिश कर रहा है जो सूसी स्मिथ ने 30 सेकंड पहले हटा दिया था, लेकिन जॉन को पता नहीं है? आपको उस मामले में डेटाबेस को हिट करने की आवश्यकता है।
युशा

4
@Yusha क्यों? दोनों परिदृश्यों में परिणाम यह है कि रिकॉर्ड चला गया है। क्या हम वास्तव में परवाह करते हैं कि अब हुआ या 30 सेकंड पहले? कुछ दौड़ की स्थिति सिर्फ इतना दिलचस्प नहीं है कि ट्रैक रखने के लिए।
9Rune5

13
  var stud = (from s1 in entities.Students
            where s1.ID== student.ID
            select s1).SingleOrDefault();

  //Delete it from memory
  entities.DeleteObject(stud);
  //Save to database
  entities.SaveChanges();

2
FirstOrDefaultखतरनाक है। या तो आप जानते हैं कि केवल एक ही है (इसलिए उपयोग SingleOrDefault), या एक से अधिक है, और यह एक लूप में किया जाना चाहिए।
मार्क सोउल

8
Employer employer = context.Employers.First(x => x.EmployerId == 1);

context.Customers.DeleteObject(employer);
context.SaveChanges();

क्या यह रक्षा करता है यदि Id 1 के साथ कोई वस्तु नहीं है? क्या यह अपवाद नहीं होगा?
जैक फेयरफील्ड

@JackFairfield मुझे लगता है कि आपको अशक्त वस्तु की जांच करनी चाहिए। और इसके अनुसार निष्कासन करें।
जवन सिंह

Firstखतरनाक है। या तो आप जानते हैं कि केवल एक ही है (इसलिए उपयोग करें Single), या एक से अधिक है, और यह एक लूप में किया जाना चाहिए।
मार्क सोउल

5

मैं LINQ के साथ एंटिटी फ्रेमवर्क का उपयोग कर रहा हूं। निम्नलिखित कोड मेरे लिए सहायक था;

1- कई रिकॉर्ड के लिए

 using (var dbContext = new Chat_ServerEntities())
 {
     var allRec= dbContext.myEntities;
     dbContext.myEntities.RemoveRange(allRec);
     dbContext.SaveChanges();
 }

2- एकल रिकॉर्ड के लिए

 using (var dbContext = new Chat_ServerEntities())
 {
     var singleRec = dbContext.ChatUserConnections.FirstOrDefault( x => x.ID ==1);// object your want to delete
     dbContext.ChatUserConnections.Remove(singleRec);
     dbContext.SaveChanges();
 }

एकल रिकॉर्ड के लिए क्यों नहीं के SingleOrDefaultबजाय का उपयोग करें FirstOrDefault?
मार्क सॉलुल

जब भी आप SingleOrDefault का उपयोग करते हैं, तो आप स्पष्ट रूप से कहते हैं कि क्वेरी को एक ही परिणाम में परिणाम करना चाहिए। दूसरी ओर, जब FirstOrDefault प्रयोग किया जाता है, क्वेरी परिणामों की किसी भी राशि वापस कर सकते हैं, लेकिन आप कहते हैं कि आप केवल पहले एक चाहते stackoverflow.com/a/1745716/3131402
Baqer नकवी

1
हां, तो एक से अधिक रिकॉर्ड होने पर, एक मनमाना रिकॉर्ड हटाना क्यों सही होगा? विशेष रूप से इस मामले में आईडी कुंजी है, इसलिए एक होना चाहिए: यदि एक से अधिक है, तो यह एक बग है (जो एकल का पता लगाएगा)
मार्क सोउल

@MarkSowul आप सही हैं। मैंने FirstOrDefault का उपयोग करने का उत्तर संपादित किया है।
बकर नकवी

@BaqerNaqvi RemoveRange परफॉर्मेंस के नजरिए से इकाई को हटाने का भयानक तरीका है .. खासकर तब जब आपकी संस्था विदेशी कुंजियों द्वारा सभी नेविगेशनल गुणों से भारी हो। मैं इसके बजाय var sql = "DELETE FROM YOUR_TABLE का उपयोग करेगा जहां आपका_फेल्ड = @your_parameter"; this.your_context.Database.ExecuteSqlCommand (sql, new SqlParameter ("@ your_parameter", yourParameter));
जिज्ञासु बोय २४'१

2

अधिक सामान्य approuch

public virtual void Delete<T>(int id) where T : BaseEntity, new()
{
    T instance = Activator.CreateInstance<T>();
    instance.Id = id;
    if (dbContext.Entry<T>(entity).State == EntityState.Detached)
    {
        dbContext.Set<T>().Attach(entity);
    }

    dbContext.Set<T>().Remove(entity);
}

2

एंटिटी फ्रेमवर्क 6 के साथ, आप उपयोग कर सकते हैं Remove। यह भी usingसुनिश्चित करने के लिए कि आपका कनेक्शन बंद है, इसका उपयोग करने के लिए एक अच्छी रणनीति है।

using (var context = new EmployDbContext())
{
    Employ emp = context.Employ.Where(x => x.Id == id).Single<Employ>();
    context.Employ.Remove(emp);
    context.SaveChanges();
}

1

बस उन तीन तरीकों का योगदान करना चाहता था जिन्हें मैंने आगे और पीछे उछाल दिया है।

विधि 1:

var record = ctx.Records.FirstOrDefault();
ctx.Records.Remove(record);
ctx.SaveChanges();

विधि 2:

var record = ctx.Records.FirstOfDefault();
ctx.Entry(record).State = EntityState.Deleted;
ctx.SaveChanges();
ctx.Entry(record).State = EntityState.Detached;

मेथड 2 के साथ जाने का एक कारण यह है कि ईएफ या ईएफसीओआर सेट करने के मामले में QueryTrackingBehavior.NoTrackingऐसा करने के लिए सुरक्षित है।

फिर विधि 3 है:

var record = ctx.Records.FirstOrDefault();
var entry = ctx.Entry(record);
record.DeletedOn = DateTimeOffset.Now;
entry.State = EntityState.Modified;
ctx.SaveChanges();
entry.State = EntityState.Detached;

यह रिकॉर्ड की DeletedOnसंपत्ति को सेट करके सॉफ्ट डिलीट अप्रोच का उपयोग करता है , और फिर भी भविष्य में उपयोग के लिए रिकॉर्ड रखने में सक्षम है, जो कभी भी हो सकता है। असल में, इसे रीसायकल बिन में डाल दिया


इसके अलावा, विधि 3 के संबंध में , पूरे रिकॉर्ड को संशोधित करने के लिए सेट करने के बजाय:

entry.State = EntityState.Modified;

आप केवल DeletedOnसंशोधित रूप में केवल कॉलम सेट करेंगे:

entry.Property(x => x.DeletedOn).IsModified = true;

0
    [HttpPost]
    public JsonResult DeleteCotnact(int id)
    {
        using (MycasedbEntities dbde = new MycasedbEntities())
        {
            Contact rowcontact = (from c in dbde.Contact
                                     where c.Id == id
                                     select c).FirstOrDefault();

            dbde.Contact.Remove(rowcontact);
            dbde.SaveChanges();

            return Json(id);
        }
    }

आप इस बारे में क्या सोचते हैं, सरल या नहीं, आप यह भी कोशिश कर सकते हैं:

        var productrow = cnn.Product.Find(id);
        cnn.Product.Remove(productrow);
        cnn.SaveChanges();

0

सामान्य डीएओ के लिए मेरा काम इस प्रकार है:

    public void Detele(T entity)
    {
        db.Entry(entity).State = EntityState.Deleted;
        db.SaveChanges();
    }


0

आप इसे इस तरह से कर सकते हैं

   public ActionResult Delete(int? id)
    {
        using (var db = new RegistrationEntities())
        {
            Models.RegisterTable Obj = new Models.RegisterTable();
            Registration.DAL.RegisterDbTable personalDetail = db.RegisterDbTable.Find(id);
            if (personalDetail == null)
            {
                return HttpNotFound();
            }
            else
            {
                Obj.UserID = personalDetail.UserID;
                Obj.FirstName = personalDetail.FName;
                Obj.LastName = personalDetail.LName;
                Obj.City = personalDetail.City;

            }
            return View(Obj);
        }
    }


    [HttpPost, ActionName("Delete")]

    public ActionResult DeleteConfirmed(int? id)
    {
        using (var db = new RegistrationEntities())
        {
            Registration.DAL.RegisterDbTable personalDetail = db.RegisterDbTable.Find(id);
            db.RegisterDbTable.Remove(personalDetail);
            db.SaveChanges();
            return RedirectToAction("where u want it to redirect");
        }
    }

नमूना

 public class RegisterTable
{

    public int UserID
    { get; set; }


    public string FirstName
    { get; set; }


    public string LastName
    { get; set; }


    public string Password
    { get; set; }


    public string City
    { get; set; }

} 

किस दृश्य से आप इसे कॉल करेंगे

 <table class="table">
    <tr>
        <th>
            FirstName
        </th>
        <th>
            LastName
        </th>

        <th>
            City
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td> @item.FirstName </td>
            <td> @item.LastName </td>
            <td> @item.City</td>
            <td>
                <a href="@Url.Action("Edit", "Registeration", new { id = item.UserID })">Edit</a> |
                <a href="@Url.Action("Details", "Registeration", new { id = item.UserID })">Details</a> |
                <a href="@Url.Action("Delete", "Registeration", new { id = item.UserID })">Delete</a>

            </td>
        </tr>

    }

</table>

मुझे उम्मीद है कि यू को समझना आसान होगा


0

आप अपने क्लिक में या अपने ग्रिड के सिल्डडब्लॉगक्लिक घटना में कुछ ऐसा कर सकते हैं (यदि आपने एक का उपयोग किया है)

if(dgEmp.CurrentRow.Index != -1)
 {
    employ.Id = (Int32)dgEmp.CurrentRow.Cells["Id"].Value;
    //Some other stuff here
 }

फिर अपने डिलीट बटन में कुछ इस तरह करें:

using(Context context = new Context())
{
     var entry = context.Entry(employ);
     if(entry.State == EntityState.Detached)
     {
        //Attached it since the record is already being tracked
        context.Employee.Attach(employ);
     }                             
     //Use Remove method to remove it virtually from the memory               
     context.Employee.Remove(employ);
     //Finally, execute SaveChanges method to finalized the delete command 
     //to the actual table
     context.SaveChanges();

     //Some stuff here
}

वैकल्पिक रूप से, आप LINQ To Entities Query का उपयोग करने के बजाय एक LINQ क्वेरी का उपयोग कर सकते हैं:

var query = (from emp in db.Employee
where emp.Id == employ.Id
select emp).Single();

Employment.Id का उपयोग फ़िल्टरिंग पैरामीटर के रूप में किया जाता है जो पहले ही आपके DataGridView के CellDoubleClick इवेंट से पास हो गया था।


कोड के पीछे आइडिया है कि आप जिस आईडी (एम्प्लॉई क्लास) को हटाना चाहते हैं उस रिकॉर्ड की आईडी (एम्प्लॉइ.आई.डी.) को वायर कर दें और फिर उसे कॉन्टेक्ट से वास्तविक टेबल पर अटैच करें फिर इन-मेमोरी रिमूव () मेथड को निष्पादित करें अंत में SaveChanges () मेथड का उपयोग करके डेटाबेस में वास्तविक बचत को निष्पादित करें। हालांकि LINQ Query भी ठीक काम करती है लेकिन मुझे रिकॉर्ड की आईडी प्राप्त करने के लिए टेबल पर क्वेरी करने का विचार पसंद नहीं है।
अरविन एक्वियो

0

यहाँ एक सुरक्षित तरीका है:

using (var transitron = ctx.Database.BeginTransaction())
{
  try
  {
    var employer = new Employ { Id = 1 };
    ctx.Entry(employer).State = EntityState.Deleted;
    ctx.SaveChanges();
    transitron.Commit();
  }
  catch (Exception ex)
  {
    transitron.Rollback();
    //capture exception like: entity does not exist, Id property does not exist, etc...
  }
}

यहां आप अपने इच्छित सभी परिवर्तनों को ढेर कर सकते हैं, इसलिए आप SaveChanges और प्रतिबद्ध से पहले विलोपन की एक श्रृंखला कर सकते हैं, इसलिए उन्हें केवल तभी लागू किया जाएगा जब वे सभी सफल होंगे।


0

सबसे अच्छा तरीका है कि जांच करें और फिर हटाएं

        if (ctx.Employ.Any(r=>r.Id == entity.Id))
        {
            Employ rec = new Employ() { Id = entity.Id };
            ctx.Entry(rec).State = EntityState.Deleted;
            ctx.SaveChanges();
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.