更新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();
所需的一个项目的检索不应该生成一个新的查询。