[entity-framework-6] 엔티티 프레임 워크 코어를 사용하여 레코드를 업데이트하는 방법은 무엇입니까?

엔티티 프레임 작업 코어에서 데이터베이스 테이블 데이터를 업데이트하는 가장 좋은 방법은 무엇입니까?

  1. 테이블 행을 검색하고 변경을 수행하고 저장하십시오.
  2. DB 컨텍스트에서 키워드 업데이트 를 사용 하고 존재하지 않는 항목에 대한 예외 처리

EF6에서 사용할 수있는 향상된 기능은 무엇입니까?



답변

Entity Framework Core로 엔터티를 업데이트하기위한 논리적 프로세스는 다음과 같습니다.

  1. DbContext클래스에 대한 인스턴스 만들기
  2. 키로 항목 검색
  3. 엔터티 속성 변경
  4. 변경 사항을 저장하다

Update()방법 DbContext:

SaveChanges()호출 될 때 데이터베이스에서 업데이트되도록 수정 됨 상태에서 지정된 엔티티 추적을 시작합니다 .

업데이트 방법은 데이터베이스에 변경 사항을 저장하지 않습니다. 대신 DbContext 인스턴스의 항목에 대한 상태를 설정합니다.

따라서 Update()데이터베이스에 변경 사항을 저장하기 전에 메서드를 호출 할 수 있습니다 .

귀하의 질문에 답하기 위해 몇 가지 객체 정의를 가정하겠습니다.

  1. 데이터베이스 이름은 Store입니다.

  2. 테이블 이름은 제품입니다.

제품 클래스 정의 :

DbContext 클래스 정의 :

엔티티 업데이트 로직 :


답변

Microsoft 문서 에 따르면 :

읽기 우선 접근 방식에는 추가 데이터베이스 읽기가 필요하며 동시성 충돌을 처리하기 위해 더 복잡한 코드가 발생할 수 있습니다.

그러나 DbContext에서 Update 메서드를 사용하면 모든 필드가 수정 된 것으로 표시되고 모든 필드 가 쿼리에 포함 된다는 것을 알아야 합니다. 필드의 하위 집합을 업데이트하려면 Attach 메서드를 사용한 다음 원하는 필드를 수동 으로 수정 된 것으로 표시 해야합니다.


답변

public async Task<bool> Update(MyObject item)
{
    Context.Entry(await Context.MyDbSet.FirstOrDefaultAsync(x => x.Id == item.Id)).CurrentValues.SetValues(item);
    return (await Context.SaveChangesAsync()) > 0;
}


답변

Microsoft Docs 는 두 가지 접근 방식을 제공합니다.

권장 HttpPost 편집 코드 : 읽기 및 업데이트

이것은 이전 버전의 Entity Framework에서 사용했던 것과 동일한 이전 방식입니다. 이것이 Microsoft가 우리에게 권장하는 것입니다.

장점

  • 초과 게시 방지
  • EF의 자동 변경 내용 추적은 Modified양식 입력에 의해 변경되는 필드에 플래그를 설정합니다 .

대체 HttpPost 편집 코드 : 생성 및 첨부

대안은 모델 바인더로 만든 엔터티를 EF 컨텍스트에 연결하고 수정 된 것으로 표시하는 것입니다.

다른 답변에서 언급했듯이 읽기 우선 접근 방식에는 추가 데이터베이스 읽기가 필요하며 동시성 충돌을 처리하기 위해 더 복잡한 코드가 발생할 수 있습니다.


답변

아주 간단합니다

using (var dbContext = new DbContextBuilder().BuildDbContext())
{
    dbContext.Update(entity);
    await dbContext.SaveChangesAsync();
}


답변

모든 답을 살펴본 후 두 가지 간단한 옵션을 추가 할 것이라고 생각했습니다.

  1. 추적이 활성화 된 상태에서 FirstOrDefault ()를 사용하여 레코드에 이미 액세스하고 (추적을 비활성화하므로 .AsNoTracking () 함수를 사용하지 않고) 일부 필드를 업데이트 한 경우 간단히 context.SaveChanges ()를 호출 할 수 있습니다.

  2. 다른 경우에는 HtppPost를 사용하여 서버에 엔티티를 게시했거나 어떤 이유로 추적을 비활성화 한 다음 context.SaveChanges () 전에 context.Update (entityName)를 호출해야합니다.

첫 번째 옵션은 변경 한 필드 만 업데이트하지만 두 번째 옵션은 실제로 업데이트 된 필드 값이 없더라도 데이터베이스의 모든 필드를 업데이트합니다. 🙂


답변

보다 일반적인 접근 방식

이 접근 방식을 단순화하기 위해 “id”인터페이스가 사용됩니다.

public interface IGuidKey
{
    Guid Id { get; set; }
}

도우미 방법

    public static void Modify<T>(this DbSet<T> set, Guid id, Action<T> func)
        where T : class, IGuidKey, new()
    {
        var target = new T
        {
            Id = id
        };
        var entry = set.Attach(target);
        func(target);
        foreach (var property in entry.Properties)
        {
            var original = property.OriginalValue;
            var current = property.CurrentValue;

            if (ReferenceEquals(original, current))
            {
                continue;
            }

            if (original == null)
            {
                property.IsModified = true;
                continue;
            }

            var propertyIsModified = !original.Equals(current);
            property.IsModified = propertyIsModified;
        }
    }

용법

dbContext.Operations.Modify(id, x => { x.Title = "aaa"; });