¿Actualizas un registro sin consultar primero?

Digamos que consulto la base de datos y cargo una lista de artículos. A continuación, abro uno de los elementos en una vista detallada, y en lugar de volver a consultar el elemento fuera de la base de datos, creo una instancia del elemento del origen de datos en la lista.

¿Hay alguna manera de actualizar el registro de la base de datos sin recuperar el registro del elemento individual?

Aquí hay una muestra de cómo lo estoy haciendo ahora:

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

Luego, después de sacar el registro, actualizo algunos valores en el artículo y vuelvo a presionar la grabación:

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

Pensaría que habría una mejor manera de hacer esto, ¿alguna idea?

Debe usar el método Attach () .

Adjuntar y separar objetos

También puede usar SQL directo en la base de datos utilizando el contexto del almacén de datos. Ejemplo:

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

Por motivos de rendimiento, es posible que desee pasar variables en lugar de una única cadena SQL codificada. Esto permitirá que SQL Server guarde en caché la consulta y la reutilice con parámetros. Ejemplo:

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

ACTUALIZACIÓN – para EF 6.0

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

Si el DataItem tiene campos que EF validará previamente (como campos que no DataItem ), tendremos que desactivar esa validación para este contexto:

 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; 

De lo contrario, podemos tratar de satisfacer la prevalidación y solo actualizar la única columna:

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

Suponiendo que dataEntity es un System.Data.Entity.DbContext

Puede verificar la consulta generada al agregar esto al DbContext :

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

El código:

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

El resultado TSQL:

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

Nota:

La línea “IsModified = true” es necesaria porque cuando crea el nuevo objeto ExampleEntity (solo con la propiedad Id rellena), todas las demás propiedades tienen sus valores predeterminados (0, nulo, etc.). Si desea actualizar el DB con un “valor predeterminado”, el marco de la entidad no detectará el cambio y, a continuación, DB no se actualizará.

Por ejemplo:

 exampleEntity.ExampleProperty = null; 

no funcionará sin la línea “IsModified = true”, porque la propiedad PropertyProperty ya es nula cuando creó el objeto ExampleEntity vacío, necesita decirle a EF que esta columna debe actualizarse, y este es el propósito de esta línea.

Este artículo, como parte de Getting Started de Microsoft, explica los estados de las entidades y cómo hacer esto:

Agregar / Adjuntar y Estados de Entidad

Mire la sección ‘Adjuntar una entidad existente pero modificada al contexto’

Ahora me voy a leer el rest de estos tutoriales.

En general, si utilizó Entity Framework para consultar todos los artículos y guardó el objeto de entidad, puede actualizar los elementos individuales en el objeto de entidad y llamar a SaveChanges() cuando haya terminado. Por ejemplo:

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

La recuperación del artículo que desea no debe generar una nueva consulta.

Funciona algo diferente en EF Core:

Puede haber una manera más rápida de hacer esto en EF Core, pero lo siguiente asegura una ACTUALIZACIÓN sin tener que hacer un SELECTO (probado con EF Core 2 y JET en .NET Framework 4.6.2):

Asegúrate de que tu modelo no tenga las propiedades de IsRequired

Luego use la siguiente plantilla (en 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