다음을 통해 공유


엔터티 상태 작업

이 항목에서는 컨텍스트에 엔터티를 추가하고 연결하는 방법과 SaveChanges 중에 Entity Framework가 이러한 엔터티를 처리하는 방법을 설명합니다. Entity Framework는 엔터티가 컨텍스트에 연결된 동안 엔터티 상태를 추적하지만 연결이 끊어진 경우나 N 계층 시나리오에서는 엔터티가 어떤 상태에 있어야 하는지 EF에 알릴 수 있습니다. 이 토픽에서 설명하는 방법은 Code First 및 EF 디자이너를 사용하여 만든 모델에 동일하게 적용됩니다.

엔터티 상태 및 SaveChanges

엔터티는 EntityState 열거형으로 정의된 다음 5가지 상태 중 하나일 수 있습니다. 각 상태는 다음과 같습니다.

  • Added: 엔터티가 컨텍스트로 추적되지만 아직 데이터베이스에 없음
  • Unchanged: 엔터티가 컨텍스트로 추적되고 데이터베이스에 있으며 해당 속성 값이 데이터베이스의 값에서 변경되지 않았음
  • Modified: 엔터티가 컨텍스트로 추적되고 데이터베이스에 있으며 해당 속성 값의 일부 또는 전부가 수정됨
  • Deleted: 엔터티가 컨텍스트로 추적되고 데이터베이스에 있지만 다음에 SaveChanges가 호출될 때 데이터베이스에서 삭제로 표시됨
  • Detached: 엔터티가 컨텍스트로 추적되지 않음

SaveChanges는 각 상태의 엔터티에 대해 다른 작업을 수행합니다.

  • Unchanged 엔터티는 SaveChanges가 아무런 작업도 하지 않습니다. Unchanged 상태의 엔터티에 대한 업데이트는 데이터베이스로 전송되지 않습니다.
  • Added 엔터티는 데이터베이스에 삽입된 다음 SaveChanges가 반환될 때 Unchanged로 전환됩니다.
  • Modified 엔터티는 데이터베이스에서 업데이트된 다음 SaveChanges가 반환될 때 Unchanged로 전환됩니다.
  • Deleted 엔터티는 데이터베이스에서 삭제된 다음 컨텍스트에서 분리됩니다.

다음 예제에서는 엔터티 또는 엔터티 그래프의 상태를 변경할 수 있는 방법을 보여줍니다.

컨텍스트에 새 엔터티 추가

DbSet에서 Add 메서드를 호출하여 컨텍스트에 새 엔터티를 추가할 수 있습니다. 이렇게 하면 엔터티가 Added 상태로 전환됩니다. 즉, 다음에 SaveChanges가 호출될 때 데이터베이스에 삽입됩니다. 예시:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Blogs.Add(blog);
    context.SaveChanges();
}

컨텍스트에 새 엔터티를 추가하는 또 다른 방법은 상태를 Added로 변경하는 것입니다. 예시:

using (var context = new BloggingContext())
{
    var blog = new Blog { Name = "ADO.NET Blog" };
    context.Entry(blog).State = EntityState.Added;
    context.SaveChanges();
}

마지막으로, 이미 추적 중인 다른 엔터티에 연결하여 컨텍스트에 새 엔터티를 추가할 수 있습니다. 다른 엔터티의 컬렉션 탐색 속성에 새 엔터티를 추가하거나 다른 엔터티의 참조 탐색 속성을 설정하여 새 엔터티를 가리킬 수 있습니다. 예시:

using (var context = new BloggingContext())
{
    // Add a new User by setting a reference from a tracked Blog
    var blog = context.Blogs.Find(1);
    blog.Owner = new User { UserName = "johndoe1987" };

    // Add a new Post by adding to the collection of a tracked Blog
    blog.Posts.Add(new Post { Name = "How to Add Entities" });

    context.SaveChanges();
}

이 모든 예제에서 추가되는 엔터티에 아직 추적되지 않은 다른 엔터티에 대한 참조가 있는 경우 해당하는 새 엔터티도 컨텍스트에 추가되고 다음에 SaveChanges가 호출될 때 데이터베이스에 삽입됩니다.

컨텍스트에 기존 엔터티 연결

데이터베이스에 이미 있지만 현재 컨텍스트로 추적되지 않는 엔터티가 있는 경우 DbSet에서 Attach 메서드를 사용하여 엔터티를 추적하도록 컨텍스트에 알릴 수 있습니다. 엔터티는 컨텍스트에서 Unchanged 상태입니다. 예시:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);

    // Do some more work...  

    context.SaveChanges();
}

연결된 엔터티를 더 조작하지 않고 SaveChanges를 호출하는 경우 데이터베이스는 변경되지 않습니다. 엔터티가 Unchanged 상태이기 때문입니다.

기존 엔터티를 컨텍스트에 연결하는 또 다른 방법은 상태를 Unchanged로 변경하는 것입니다. 예시:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

이 두 예제에서 연결되는 엔터티에 아직 추적되지 않은 다른 엔터티에 대한 참조가 있는 경우 해당하는 새 엔터티도 Unchanged 상태의 컨텍스트에 연결됩니다.

기존에 있었지만 수정된 엔터티를 컨텍스트에 연결

데이터베이스에 이미 있지만 변경했을 수도 있는 엔티티가 있는 경우 컨텍스트에 엔터티를 연결하고 Modified 상태로 설정하도록 알릴 수 있습니다. 예시:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;

    // Do some more work...  

    context.SaveChanges();
}

상태를 Modified로 변경하면 엔터티의 모든 속성이 수정된 것으로 표시되고 SaveChanges가 호출될 때 모든 속성 값이 데이터베이스로 전송됩니다.

연결되는 엔터티에 아직 추적되지 않은 다른 엔터티에 대한 참조가 있는 경우 해당하는 새 엔터티는 Unchanged 상태의 컨텍스트에 연결되며 Modified로 자동 전환되지 않습니다. Modified로 표시해야 하는 여러 엔터티가 있는 경우 각 엔터티 상태를 개별적으로 설정해야 합니다.

추적된 엔터티 상태 변경

항목에서 State 속성을 설정하여 이미 추적 중인 엔터티의 상태를 변경할 수 있습니다. 예시:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

이미 추적된 엔터티에 대해 Add 또는 Attach 호출을 사용하여 엔터티 상태를 변경할 수도 있습니다. 예를 들어 현재 Added 상태인 엔터티에 대해 Attach를 호출하면 상태가 Unchanged로 변경됩니다.

패턴 삽입 또는 업데이트

일부 애플리케이션의 일반적인 패턴은 기본 키의 값에 따라 엔터티를 새 엔터티로 추가(데이터베이스 삽입)하거나 엔터티를 기존 엔터티로 연결하고 수정된 것으로 표시(데이터베이스 업데이트)하는 것입니다. 예를 들어 데이터베이스에서 생성된 정수 기본 키를 사용하는 경우 0 키가 있는 엔터티를 새 엔터티로 처리하고, 0이 아닌 키가 있는 엔터티를 기존 엔터티로 처리하는 것이 일반적입니다. 이 패턴은 기본 키 값의 확인을 기반으로 엔터티 상태를 설정하여 이루어집니다. 예시:

public void InsertOrUpdate(Blog blog)
{
    using (var context = new BloggingContext())
    {
        context.Entry(blog).State = blog.BlogId == 0 ?
                                   EntityState.Added :
                                   EntityState.Modified;

        context.SaveChanges();
    }
}

상태를 Modified로 변경하면 엔터티의 모든 속성이 수정된 것으로 표시되고 SaveChanges가 호출될 때 모든 속성 값이 데이터베이스로 전송됩니다.