Entity Framework에서 단일 레코드를 삭제 하시겠습니까?


195

Entity Framework에라 employ는 단일 키 열로 이름이 지정된 SQL Server 테이블이 ID있습니다.

Entity Framework를 사용하여 테이블에서 단일 레코드를 어떻게 삭제합니까?


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

2
@CarterMedlin-작동하는 동안 SELECT와 DELETE라는 두 가지 데이터베이스 적중입니다. 대부분의 사람들은 선택이 삭제보다 시간이 훨씬 오래 걸리기 때문에 매우 낭비 적이라는 것을 알고 있습니다.
— Davor

성능 문제로 인해 엔터티 프레임 워크 Remove 또는 RemoveRange를 사용하지 않는 것이 좋습니다. 차라리 다음과 같이 매우 간단한 것을 사용하려고합니다. var sql = "DELETE FROM YOUR_TABLE WHERE YOUR_FIELD = @your_parameter"; this.your_context.Database.ExecuteSqlCommand (sql, new SqlParameter ( "@ your_parameter", yourParameter));
— curiousBoy

2
@curiousBoy 제안한대로 명령문을 실행할 때 EF6 캐시는 변경 사항을 반영하지 않는다고 생각합니다.
— Yitzchak

답변:


362

먼저 객체를 쿼리 할 필요는 없으며 ID로 컨텍스트에 연결할 수 있습니다. 이처럼 :

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
— 사이먼 Belanger 보낸

12
관계가 삭제 계단식으로 정의 된 경우에만 작동합니다. 그렇지 않으면 위 코드는 FK 예외에서 실패합니다.
— baruchl

6
@mt_serg, 3 단계 앞을보고 있습니다. DB에서 그러한 간단한 레코드를 실제로 제거해야 할 때는 언제입니까? 일반적으로 FK 관계가 포함 된보다 복잡한 레코드를 처리합니다. 따라서 내 의견.
— baruchl

2
@IanWarburton 두 번째 및 세 번째 줄 (연결 및 제거)
— Simon Belanger

4
@PaulZahra : 때로는 다른 쿼리 나 소스의 ID 목록이 있으며 삭제해야합니다. 삭제하기 위해 객체를로드하는 대신 ID로 삭제할 수 있습니다. 알다시피, DELETE 문이 SQL에서 정상적으로 작동하는 방식입니다.
— siride

82

당신이 사용할 수있는 SingleOrDefault당신의 기준과 일치하는 단일 객체를 얻기 위해, 다음에 그것을 통과 Remove하여 EF 테이블의 방법.

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

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

5
데이터베이스에서 모든 필드를 선택하기 때문에 이것은 좋은 방법이 아닙니다!
— 알리 Yousefi

2
이것이 내가하는 방법입니다.
— 잭 페어 필드

4
@Ali, Jack-그러나 삭제하려는 데이터가 실제로 존재하는지 확인하여 문제를 예방할 수 있기 때문에 이것이 바람직하다고 생각합니다. 수락 된 답변은 확인되지 않습니다.
— Michael Philips

4
이것이 더 좋은 방법입니다. 생각 해봐 John Smith가 Susie Smith가 30 초 전에 제거한 id = 1 인 항목을 제거하려고하지만 John이 모르는 경우 어떻게합니까? 이 경우 데이터베이스에 충돌해야합니다.
— Yusha

5
@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있거나 () 또는 둘 이상 이 있다는 것을 알고 루프에서 수행해야합니다.
— Mark Sowul

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

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

Id 1의 객체가없는 경우이를 보호합니까? 예외가 발생하지 않습니까?
— 잭 페어 필드

@ JackFairfield null 객체를 확인해야한다고 생각합니다. 그리고 그것에 따르면 제거를 수행하십시오.
— Jawand Singh

First위험합니다. 하나만 Single있거나 () 또는 둘 이상 이 있다는 것을 알고 루프에서 수행해야합니다.
— Mark Sowul

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?
— Mark Sowul

SingleOrDefault를 사용할 때마다 쿼리에서 최대 하나의 결과 만 발생해야한다는 것을 명확하게 명시합니다. 반면에 FirstOrDefault를 사용하는 경우 쿼리는 많은 양의 결과를 반환 할 수 있지만 첫 번째 결과 만 원한다고 진술합니다. stackoverflow.com/a/1745716/3131402
— Baqer Naqvi

1
예, 임의 레코드가 둘 이상있는 경우 임의 레코드를 삭제하는 것이 왜 정확합니까? 특히이 경우 id가 핵심이므로 하나 이상이 있어야합니다. 둘 이상이 있으면 버그입니다 (Single이 감지 할 버그)
— Mark Sowul

@MarkSowul 당신이 맞아요. FirstOrDefault를 사용하도록 답변을 편집했습니다.
— Baqer Naqvi

@BaqerNaqvi RemoveRange는 성능 관점에서 엔터티를 제거하는 끔찍한 방법입니다. 특히 엔터티가 외래 키로 모든 탐색 속성을 가지고있는 경우. 오히려 var sql = "YOUR_TABLE WHERE YOUR_FIELD = @your_parameter에서 삭제"; this.your_context.Database.ExecuteSqlCommand (sql, new SqlParameter ( "@ your_parameter", yourParameter));
— curiousBoy

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

Entity Framework 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를 선호하는 이유 중 하나는 EF 또는 EFCore를로 설정 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

일반적인 DAO의 경우 내 작품은 다음과 같습니다.

    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

그리드의 클릭 또는 celldoubleclick 이벤트에서 이와 같은 작업을 수행 할 수 있습니다 (사용한 경우)

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 엔터티 쿼리를 사용하는 대신 LINQ 쿼리를 사용할 수 있습니다.

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

adopt.Id 는 DataGridView의 CellDoubleClick 이벤트에서 이미 전달 된 필터링 매개 변수로 사용됩니다.


코드 뒤에 아이디어는 삭제하려는 레코드의 id (employ.Id)를 모델 (직원 클래스)에 연결 한 다음 컨텍스트에서 실제 테이블에 첨부 한 다음 메모리 내 Remove () 메소드를 실행하는 것입니다. 마지막으로 SaveChanges () 메소드를 사용하여 데이터베이스에 실제 저장을 실행하십시오. LINQ Query도 제대로 작동하지만 레코드 ID를 얻기 위해 테이블에 쿼리하는 아이디어는 마음에 들지 않습니다.
— arvin aquio

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 및 Commit 전에 일련의 삭제를 수행 할 수 있으므로 모두 성공한 경우에만 적용됩니다.


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();
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.