[c#] 먼저 쿼리하지 않고 레코드를 업데이트 하시겠습니까?

데이터베이스를 쿼리하고 항목 목록을로드한다고 가정 해 보겠습니다. 그런 다음 세부 정보보기 양식에서 항목 중 하나를 열고 데이터베이스에서 항목을 다시 쿼리하는 대신 목록의 데이터 원본에서 항목의 인스턴스를 만듭니다.

개별 항목의 레코드를 가져 오지 않고 데이터베이스 레코드를 업데이트 할 수있는 방법이 있습니까?

다음은 내가 지금 수행하는 방법의 샘플입니다.

dataItem itemToUpdate = (from t in dataEntity.items
                                 where t.id == id
                                 select t).FirstOrDefault();

그런 다음 레코드를 가져온 후 항목의 일부 값을 업데이트하고 레코드를 다시 푸시합니다.

itemToUpdate.itemstatus = newStatus;
dataEntity.SaveChanges();

이 작업을 수행하는 더 좋은 방법이 있다고 생각합니다. 어떤 아이디어라도 있습니까?



답변

Attach () 메서드를 사용해야합니다 .

개체 연결 및 분리


답변

데이터 스토어의 컨텍스트를 사용하여 데이터베이스에 대해 직접 SQL을 사용할 수도 있습니다. 예:

dataEntity.ExecuteStoreCommand
   ("UPDATE items SET itemstatus = 'some status' WHERE id = 123 ");

성능상의 이유로 하드 코딩 된 단일 SQL 문자열 대신 변수를 전달할 수 있습니다. 이렇게하면 SQL Server가 쿼리를 캐시하고 매개 변수와 함께 재사용 할 수 있습니다. 예:

dataEntity.ExecuteStoreCommand
   ("UPDATE items SET itemstatus = 'some status' WHERE id = {0}", new object[] { 123 });

업데이트-EF 6.0 용

dataEntity.Database.ExecuteSqlCommand
       ("UPDATE items SET itemstatus = 'some status' WHERE id = {0}", new object[] { 123 });


답변

코드:

ExampleEntity exampleEntity = dbcontext.ExampleEntities.Attach(new ExampleEntity { Id = 1 });
exampleEntity.ExampleProperty = "abc";
dbcontext.Entry<ExampleEntity>(exampleEntity).Property(ee => ee.ExampleProperty).IsModified = true;
dbcontext.Configuration.ValidateOnSaveEnabled = false;
dbcontext.SaveChanges();

결과 TSQL :

exec sp_executesql N'UPDATE [dbo].[ExampleEntities]
SET [ExampleProperty ] = @0
WHERE ([Id] = @1)
',N'@0 nvarchar(32),@1 bigint',@0='abc',@1=1

노트 :

“IsModified = true”줄은 새 ExampleEntity 개체를 만들 때 (ID 속성이 채워진 상태에서만) 다른 모든 속성에 기본값 (0, null 등)이 있기 때문에 필요합니다. “기본값”으로 DB를 업데이트하려는 경우 변경 사항이 엔티티 프레임 워크에서 감지되지 않고 DB가 업데이트되지 않습니다.

예 :

exampleEntity.ExampleProperty = null;

빈 ExampleEntity 개체를 만들 때 ExampleProperty 속성이 이미 null이므로 “IsModified = true”줄이 없으면 작동하지 않습니다.이 열을 업데이트해야한다고 EF에 알려야하며 이것이이 줄의 목적입니다.


답변

(가) 경우 DataItem(nullable이 아닌 필드와 같은) EF는 사전 검증하는 필드가 있습니다, 우리는이 상황에 대해 그 유효성을 해제해야합니다 :

DataItem itemToUpdate = new DataItem { Id = id, Itemstatus = newStatus };
dataEntity.Entry(itemToUpdate).Property(x => x.Itemstatus).IsModified = true;
dataEntity.Configuration.ValidateOnSaveEnabled = false;
dataEntity.SaveChanges();
//dataEntity.Configuration.ValidateOnSaveEnabled = true;

그렇지 않으면 사전 검증을 만족하고 단일 열만 업데이트 할 수 있습니다.

DataItem itemToUpdate = new DataItem
{
    Id = id,
    Itemstatus = newStatus,
    NonNullableColumn = "this value is disregarded - the db original will remain"
};
dataEntity.Entry(itemToUpdate).Property(x => x.Itemstatus).IsModified = true;
dataEntity.SaveChanges();

가정 dataEntitySystem.Data.Entity.DbContext

다음을 추가하여 생성 된 쿼리를 확인할 수 있습니다 DbContext.

/*dataEntity.*/Database.Log = m => System.Diagnostics.Debug.Write(m);


답변

Microsoft 시작하기의 일부인이 문서에서는 엔터티 상태와이를 수행하는 방법에 대해 설명합니다.

추가 / 첨부 및 엔티티 상태

‘기존이지만 수정 된 엔티티를 컨텍스트에 첨부’섹션을보십시오.

이제 나머지 튜토리얼을 읽어 보겠습니다.


답변

EF Core에서 약간 다르게 작동합니다.

EF Core에서이 작업을 수행하는 더 빠른 방법이있을 수 있지만 다음은 SELECT를 수행하지 않고도 UPDATE를 보장합니다 (.NET Framework 4.6.2에서 EF Core 2 및 JET로 테스트 됨).

모델에 IsRequired 속성이 없는지 확인

그런 다음 VB.NET에서 다음 템플릿을 사용합니다.

    Using dbContext = new MyContext()
        Dim bewegung = dbContext.MyTable.Attach(New MyTable())
        bewegung.Entity.myKey = someKey
        bewegung.Entity.myOtherField = "1"

        dbContext.Entry(bewegung.Entity).State = EntityState.Modified
        dbContext.Update(bewegung.Entity)

        Dim BewegungenDescription = (From tp In dbContext.Model.GetEntityTypes() Where tp.ClrType.Name = "MyTable" Select tp).First()
        For Each p In (From prop In BewegungenDescription.GetProperties() Select prop)
            Dim pp = dbContext.Entry(bewegung.Entity).Property(p.Name)
            pp.IsModified = False
        Next
        dbContext.Entry(bewegung.Entity).Property(Function(row) row.myOtherField).IsModified = True
        dbContext.SaveChanges()
    End Using


답변

일반적으로 Entity Framework를 사용하여 모든 항목을 쿼리하고 엔터티 개체를 저장 한 경우 엔터티 개체의 개별 항목을 업데이트하고 SaveChanges()완료되면 호출 할 수 있습니다. 예를 들면 :

var items = dataEntity.Include("items").items;
// For each one you want to change:
items.First(item => item.id == theIdYouWant).itemstatus = newStatus;
// After all changes:
dataEntity.SaveChanges();

원하는 항목을 검색 할 때 새 쿼리가 생성되지 않아야합니다.