데이터베이스를 쿼리하고 항목 목록을로드한다고 가정 해 보겠습니다. 그런 다음 세부 정보보기 양식에서 항목 중 하나를 열고 데이터베이스에서 항목을 다시 쿼리하는 대신 목록의 데이터 원본에서 항목의 인스턴스를 만듭니다.
개별 항목의 레코드를 가져 오지 않고 데이터베이스 레코드를 업데이트 할 수있는 방법이 있습니까?
다음은 내가 지금 수행하는 방법의 샘플입니다.
dataItem itemToUpdate = (from t in dataEntity.items
where t.id == id
select t).FirstOrDefault();
그런 다음 레코드를 가져온 후 항목의 일부 값을 업데이트하고 레코드를 다시 푸시합니다.
itemToUpdate.itemstatus = newStatus;
dataEntity.SaveChanges();
이 작업을 수행하는 더 좋은 방법이 있다고 생각합니다. 어떤 아이디어라도 있습니까?
답변
답변
데이터 스토어의 컨텍스트를 사용하여 데이터베이스에 대해 직접 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();
가정 dataEntity
은System.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();
원하는 항목을 검색 할 때 새 쿼리가 생성되지 않아야합니다.