Hapus satu catatan dari Entity Framework?


195

Saya memiliki tabel SQL Server di Entity Framework bernama employdengan satu kolom kunci bernama ID.

Bagaimana cara menghapus satu catatan dari tabel menggunakan Kerangka Entity?


2
db.employ.Remove (db.employ.Find (ID1))
Carter Medlin

2
@CarterMedlin - sementara itu akan berhasil, itu adalah dua hit basis data: satu SELECT dan satu DELETE. Kebanyakan orang merasa sangat boros, terutama karena memilih mungkin akan memakan waktu lebih lama daripada menghapus.
Davor

Saya tidak akan menyarankan untuk menggunakan kerangka kerja Remove atau RemoveRange karena masalah kinerja. Saya lebih suka menggunakan sesuatu yang super sederhana sebagai berikut: var sql = "HAPUS DARI YOUR_TABLE DI MANA YOUR_FIELD = @your_parameter"; this.your_context.Database.ExecuteSqlCommand (sql, SqlParameter baru ("@ your_parameter", yourParameter));
curiousBoy

2
@curiousBoy Saya pikir ketika Anda menjalankan pernyataan seperti yang Anda sarankan, cache EF6 tidak mencerminkan perubahan.
Yitzchak

Jawaban:


362

Itu tidak perlu untuk query objek terlebih dahulu, Anda dapat melampirkannya ke konteks dengan id-nya. Seperti ini:

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

Atau, Anda dapat mengatur status entri terlampir untuk dihapus:

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

87
Atau,ctx.Entry(employer).State = EntityState.Deleted
Simon Belanger

12
ini hanya akan berfungsi jika hubungan didefinisikan sebagai hapus kaskade. jika tidak, kode di atas akan gagal pada pengecualian FK.
baruchl

6
@ mt_serg, saya mencari 3 langkah ke depan. kapan terakhir kali Anda benar-benar harus menghapus catatan sederhana dari DB? biasanya Anda berurusan dengan catatan yang lebih kompleks yang mencakup hubungan FK. karenanya komentar saya.
baruchl

2
@IanWarburton Baris ke-2 dan ke-3 (Lampirkan dan Hapus)
Simon Belanger

4
@ PaulZahra: kadang-kadang Anda memiliki daftar ID dari beberapa kueri atau sumber lain, dan Anda perlu menghapusnya. Daripada memuat objek hanya untuk menghapusnya, dengan cara ini Anda dapat menghapus dengan ID. Anda tahu, itulah cara pernyataan DELETE bekerja di SQL secara normal.
siride

82

Anda dapat menggunakan SingleOrDefaultuntuk mendapatkan satu objek yang cocok dengan kriteria Anda, dan kemudian meneruskannya ke Removemetode tabel EF Anda.

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

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

5
ini bukan cara yang baik, karena Anda memilih semua bidang dari basis data!
Ali Yousefi

2
Ini adalah cara saya melakukannya.
Jack Fairfield

4
@ Ali, Jack - Tapi saya pikir ini lebih disukai karena pertama kali memeriksa apakah data yang Anda coba hapus benar-benar ada yang dapat mencegah masalah. Jawaban yang diterima tidak memiliki cek seperti itu.
Michael Philips

4
Ini cara yang lebih baik. Pikirkan tentang itu. Bagaimana jika John Smith mencoba untuk menghapus item dengan id = 1 yang dihapus Susie Smith 30 detik yang lalu tetapi John tidak tahu? Anda harus menekan database dalam kasus itu.
Yusha

4
@Yusha Kenapa? Dalam kedua skenario hasilnya adalah catatan hilang. Apakah kita benar-benar peduli jika itu terjadi sekarang atau 30 detik yang lalu? Beberapa kondisi balapan tidak begitu menarik untuk dilacak.
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
FirstOrDefaultberbahaya. Entah Anda tahu hanya ada satu (jadi gunakan SingleOrDefault), atau ada lebih dari satu, dan itu harus dilakukan dalam satu lingkaran.
Mark Sowul

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

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

Apakah ini melindungi jika tidak ada objek dengan Id 1? Bukankah itu melempar pengecualian?
Jack Fairfield

@JackFairfield saya pikir Anda harus memeriksa objek nol. dan menurutnya melakukan hapus.
Jawand Singh

Firstberbahaya. Entah Anda tahu hanya ada satu (jadi gunakan Single), atau ada lebih dari satu, dan itu harus dilakukan dalam satu lingkaran.
Mark Sowul

5

Saya menggunakan kerangka kerja entitas dengan LINQ. Kode berikut sangat membantu saya;

1- Untuk banyak catatan

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

2- Untuk catatan tunggal

 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();
 }

Sebagai catatan tunggal mengapa tidak menggunakan SingleOrDefaultbukan FirstOrDefault?
Mark Sowul

Setiap kali Anda menggunakan SingleOrDefault, Anda dengan jelas menyatakan bahwa kueri akan menghasilkan paling banyak satu hasil. Di sisi lain, ketika FirstOrDefault digunakan, kueri dapat mengembalikan jumlah hasil berapapun tetapi Anda menyatakan bahwa Anda hanya menginginkan yang pertama stackoverflow.com/a/1745716/3131402
Baqer Naqvi

1
Ya, jadi mengapa benar menghapus catatan sewenang-wenang, jika ada lebih dari satu? Khususnya dalam hal ini id adalah kuncinya, jadi harus ada satu: jika ada lebih dari satu, itu adalah bug (yang akan dideteksi oleh Single)
Mark Sowul

@MarkSowul Anda benar. Saya telah mengedit jawaban untuk menggunakan FirstOrDefault.
Baqer Naqvi

@ BaqerNaqvi RemoveRange adalah cara yang mengerikan untuk menghapus entitas dari perspektif kinerja .. Terutama ketika entitas Anda berat dengan semua properti navigasi dengan kunci asing. Saya lebih suka menggunakan var sql = "DELETE FROM YOUR_TABLE WHERE YOUR_FIELD = @your_parameter"; this.your_context.Database.ExecuteSqlCommand (sql, SqlParameter baru ("@ your_parameter", yourParameter));
curiousBoy

2

Persetujuan yang lebih umum

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

Dengan Entity Framework 6, Anda bisa menggunakan Remove. Juga merupakan taktik yang baik untuk digunakan usinguntuk memastikan koneksi Anda ditutup.

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

1

Hanya ingin menyumbangkan tiga metode yang telah saya bolak-balik.

Metode 1:

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

Metode 2:

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

Salah satu alasan mengapa saya lebih suka menggunakan Metode 2 adalah karena dalam hal mengatur EF atau EFCore QueryTrackingBehavior.NoTracking, itu lebih aman untuk dilakukan.

Lalu ada Metode 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;

Ini menggunakan pendekatan penghapusan lunak dengan menetapkan DeletedOnproperti catatan , dan masih dapat menyimpan catatan untuk digunakan di masa depan, apa pun itu. Pada dasarnya, menaruhnya di Recycle Bin .


Juga, sehubungan dengan Metode 3 , alih-alih mengatur seluruh catatan yang akan dimodifikasi:

entry.State = EntityState.Modified;

Anda juga hanya akan mengatur kolom yang DeletedOndimodifikasi:

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);
        }
    }

Apa pendapat Anda tentang ini, sederhana atau tidak, Anda juga dapat mencoba ini:

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

0

Untuk DAO generik pekerjaan saya finnaly ini:

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


0

kamu dapat melakukannya hanya seperti ini

   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");
        }
    }

model

 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; }

} 

lihat dari mana Anda akan menyebutnya

 <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>

Saya harap ini akan mudah bagi Anda untuk mengerti


0

Anda dapat melakukan sesuatu seperti ini di klik atau sel acara klik kotak Anda (jika Anda menggunakannya)

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

Kemudian lakukan sesuatu seperti ini di Tombol Hapus Anda:

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
}

Atau, Anda bisa menggunakan Kueri LINQ alih-alih menggunakan LINQ Ke Entitas Kueri:

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

mempekerjakan.Id digunakan sebagai parameter pemfilteran yang sudah diteruskan dari SelDoubleClick Peristiwa DataGridView Anda.


Ide di balik kode adalah Anda mengirim id (mempekerjakan.Id) dari catatan yang ingin Anda hapus ke model (Kelas Karyawan) dan kemudian melampirkannya ke Tabel aktual dari Konteks kemudian jalankan di-memori Hapus () Metode kemudian akhirnya jalankan penyimpanan aktual ke basis data menggunakan Metode SaveChanges (). Meskipun Query LINQ juga berfungsi dengan baik, tetapi saya tidak suka ide untuk menanyakan tabel hanya untuk mendapatkan id dari catatan.
arvin aquio

0

Inilah cara yang aman:

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...
  }
}

Di sini Anda dapat menumpuk semua perubahan yang Anda inginkan, sehingga Anda dapat melakukan serangkaian penghapusan sebelum SaveChanges dan Commit, sehingga mereka akan diterapkan hanya jika mereka semua berhasil.


0

Cara terbaik adalah memeriksa dan kemudian menghapus

        if (ctx.Employ.Any(r=>r.Id == entity.Id))
        {
            Employ rec = new Employ() { Id = entity.Id };
            ctx.Entry(rec).State = EntityState.Deleted;
            ctx.SaveChanges();
        }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.