program tip

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

radiobox 2020. 9. 10. 07:35
반응형

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


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

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

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

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 시작하기의 일부인이 문서에서는 엔터티 상태와이를 수행하는 방법에 대해 설명합니다.

추가 / 첨부 및 엔티티 상태

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

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


Generally speaking, if you used Entity Framework to query all the items, and you saved the entity object, you can update the individual items in the entity object and call SaveChanges() when you are finished. For example:

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();

The retrieval of the one item you want should not generate a new query.


It works somewhat different in EF Core:

There may be a faster way to do this in EF Core, but the following ensures an UPDATE without having to do a SELECT (tested with EF Core 2 and JET on the .NET Framework 4.6.2):

Ensure your model does not have IsRequired properties

Then use the following template (in 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

참고URL : https://stackoverflow.com/questions/4218566/update-a-record-without-first-querying

반응형