var user = userContext.Users.First(u => u.Id == 1);
user.Name = "John";
userContext.SaveChanges();
EF
如何知道只有名稱列已更改,因此創建SQL查詢來更新它?它如何在內部工作
EF
如何跟蹤實體?
從數據庫中獲取實體後,是否將實體的副本保留在內存中,然後將其與上下文中的修改實體進行比較?
var user = userContext.Users.First(u => u.Id == 1);
user.Name = "John";
userContext.SaveChanges();
EF
如何知道只有名稱列已更改,因此創建SQL查詢來更新它?它如何在內部工作
EF
如何跟蹤實體?
從數據庫中獲取實體後,是否將實體的副本保留在內存中,然後將其與上下文中的修改實體進行比較?
簡短的回答是肯定的。 EF保留從數據庫讀取的「原始」數據副本。你可以閱讀更多關於change tracking on MSDN。
實體框架可以爲每個跟蹤更改的模型生成一個Proxy類。本質上,它用自我跟蹤屬性包裝對象。
基本上,你可以想像它實現的是這樣的(我不知道實際的內部,但是這應該有點幫助與理論,如果你想看到準確它是如何做,你可以反編譯):
internal List<string> ChangedFields = new List<string>();
private string _name;
public string Name
{
get { return _name; }
set {
ChangedFields.Add("Name");
_name = value;
}
}
這個複製的每個字段
顯然,每個字段你做出改變,然後在ChangedFields
跟蹤。
再有,就是純粹是爲了說明目的如何可以利用工作性質有明確get
/set
,不具體實體框架是怎麼做的。
但有時您不會獲得代理,而是非代理實例。它在這種情況下如何工作? –
@OpCoder如果您要禁用代理生成,則支持'ObjectContext'實際上會執行跟蹤。當您使用上下文從數據庫中檢索對象時,它會存儲該對象的副本,並在保存時使用'DetectChanges()'來查看是否存在差異以及需要保存的內容。 –
謝謝,所以你在內存中會有被修改的對象和原始對象嗎?我想知道如何爲大量的行工作。但我想沒有其他方法讓orm跟蹤更改 –
您通常不會一次修改大量的實體。通常的工作流程涉及顯示大量記錄並讓用戶選擇一個來修改和更新。對您的DAL進行不同的操作可能很有用:使用「無跟蹤」選項的簡單「讀取」和啓用更改跟蹤時讀取的「讀取更新」。 – LeffeBrune