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.