更新logging而不先查询?

比方说,我查询数据库并加载项目列表。 然后我以详细视图的forms打开其中一个项目,而不是从数据库中重新查询项目,而是从列表中的数据源创build项目的一个实例。

有没有办法可以更新数据库logging而不需要获取单个项目的logging?

以下是我现在正在做的一个示例:

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

然后拉logging后,我更新项目中的一些值,并推回logging:

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

我想会有更好的方法来做到这一点,有什么想法?

你应该使用Attach()方法。

附加和分离对象

您也可以使用数据存储的上下文对数据库使用直接的SQL。 例:

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

出于性能原因,您可能想要传递variables而不是单个硬编码的SQLstring。 这将允许SQL Servercaching查询并重新使用参数。 例:

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

如果DataItem具有EF预先validation的字段(比如非空字段),那么我们必须对这个上下文禁用validation:

 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; 

否则,我们可以尝试满足预validation,只是更新单列:

 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

您可以validation通过将此添加到DbContext生成的查询:

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

代码:

 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 

注意:

因为当你创build新的ExampleEntity对象时(只有Id属性被填充),所有其他的属性都有它们的默认值(0,null等等),因此需要“IsModified = true”行。 如果要用“默认值”更新数据库,则entity framework不会检测到该更改,然后数据库将不会更新。

例如:

 exampleEntity.ExampleProperty = null; 

如果没有“IsModified = true”的行,就不会工作,因为在创build空的ExampleEntity对象时,属性ExampleProperty已经为null,所以您需要对EF说这个列必须更新,这就是这行的目的。

本文作为Microsoft入门的一部分解释实体状态以及如何执行此操作:

添加/附加和实体状态

查看“将现有的但已修改的实体附加到上下文”部分

现在我要阅读这些教程的其余部分。

一般来说,如果您使用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(); 

所需的一个项目的检索不应该生成一个新的查询。