2013-07-02 98 views
3

我有更新某些表的方法。爲了更新我需要得到的第一個TestProcess,但我不喜歡這一點。如何更新TestProcess而不運行select(firstOrDefault),僅用於更新操作?方法實體框架DbContext更新值無查詢和外鍵

例子:

public void UpdateTestProcess(int id, string updateID) 
{ 
    using (TestEntities context = new TestEntities()) 
       { 
        TestProcess pr = context.TestProcess.FirstOrDefault(x => x.MyID == id); 
        pr.UpdateID = updateID;    

        context.TestProcess.Attach(pr); 
        context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified); 
        context.SaveChanges(); 
       } 
} 
+0

什麼?要更新一個項目,您首先必須「獲取」它以應用更新。你爲什麼不喜歡那樣? – Jonesopolis

+0

可能是因爲它是對數據庫的額外查詢 – Andrei

+0

可能重複的[我可以更新一個EF實體而不先詢問它嗎?](http://stackoverflow.com/questions/795528/can-i-update-an- ef-entity-without-query-for-it-first) – Andrei

回答

2

你可以做這樣的(你應該有所有的測試過程的數據):

TestProcess pr = new TestProcess(); 

pr.Id = id; 
pr.UpdateID = updateID; 

context.Attach(pr); 
context.ObjectStateManager.ChangeObjectState(pr, EntityState.Modified); 
context.SaveChanges(); 
+0

這是行不通的。我有錯誤:參數1:無法從'進程'轉換爲''System.Data.Objects.DataClasses.IEntityWithKey' – zrabzdn

+0

我想context.AttachTo(「TestProcesses」,公關); \t \t \t \t context.ObjectStateManager.ChangeObjectState(pr,EntityState.Modified); \t \t \t \t context.TestProcesses.MergeOption = MergeOption.OverwriteChanges; \t \t \t \t context.AcceptAllChanges();但不保存更改 – zrabzdn

6
TestProcess pr = new TestProcess() 
{ 
    MyID == id, 
}; 

context.Set<TestProcess>().Attach(pr); 

pr.UpdateID = updateID; 

context.SaveChanges(); 

如果要設置值的該類型的默認值(例如,將int設置爲0),它將不會被視爲更改,您需要手動設置狀態。

pr.UpdateID = updateID; 
context.Entry(pr).Property(p => p.UpdateID).IsModified = true; 

可以在擴展方法把這樣的代碼了,所以你可以做這樣的事情(我會離開的實現作爲一個練習):

Foo entity = this.DbContext.GetEntityForUpdate<Foo>(
    item => item.ID, model.ID 
    ); 

this.DbContext.UpdateProperty(entity, item => item.Name, model.Name); 
+0

如果我使用ObjectContext,如何實現您的示例? – zrabzdn

+0

爲什麼要在EF 5中使用ObjectContext? – Stijn

+0

在這種情況下,我無法幫到你。 DbContext現在已經推薦了一段時間,如果情況允許,你應該使用它。 – Stijn

1

代碼:

TestProcess testprocess = dbcontext.TestProcesses.Attach(new TestProcess { MyID = id }); 
tp.UpdateID = updateID; 
dbcontext.Entry<TestProcess>(testprocess).Property(tp => tp.UpdateID).IsModified = true; 
dbcontext.Configuration.ValidateOnSaveEnabled = false; 
dbcontext.SaveChanges(); 

結果TSQL:

exec sp_executesql N'UPDATE [dbo].[TestProcesses] 
SET [UpdateID] = @0 
WHERE ([MyID] = @1) 
',N'@0 bigint,@1 bigint',@0=2,@1=1 

注意:

「IsModified = true」行是必需的,因爲當您創建新的TestProcess對象時(僅在MyID屬性填充時),所有其他屬性都具有其默認值(0,null等)。如果您想用「默認值」更新數據庫,更改將不會被實體框架檢測到,然後數據庫將不會更新。

在例如:

testprocess.UpdateID = null; 

無行「IsModified =真」是行不通的,因爲物業UpdateID,已經是空當您創建的空TestProcess對象,你需要告訴EF這列必須更新,這是這一行的目的。