一.約定
OnModelCreating 有一些限制需要注意,例如:
1.表名不支持使用標簽進行標注
2.最小長度在 OnModelCreating 中不支持
3.正則表達式在 OnModelCreating 中不支持
使用標注來豐富模型的驗證規則
使用 OnModelCreated 來完成數據庫的約束(主鍵,自增長,表名,列類型等等)
二.加載
Include:貪婪加載
var orders = from o in context.Orders.Include("OrderDetails")
where o.CustomerName == "Mac"
select o;
延遲加載
另外一個特性就是延遲加載,默認情況下,延遲加載被支持,如果你希望禁用它,必須顯式聲明,最好的位置是在 DbContext 的構造器中。
public MyDomainContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
當 EF 訪問實體的子實體的時候是如何工作的呢?在訪問的時候沒有事件發生,EF 通過從你定義的實體派生一個動態的對象,然后覆蓋你的子實體集合訪問屬性來實現。這就是為什么需要標記你的子實體集合屬性為 virtual 的原因。
總結一下兩種加載方式的特點
貪婪加載:
1.減少數據訪問的延遲,在一次數據庫的訪問中返回所有的數據。
2.你需要知道你將作什么,並且顯式聲明
延遲加載:
1.非常寬容,因為只在需要的時候加載數據,不需要預先計划
2.可能因為數據訪問的延遲而降低性能,考慮到每訪問父實體的子實體時,就需要訪問數據庫。
所以遇到循環應該采用貪婪加載,否則每次循環都會訪問數據庫
EF中對實體狀會有4種狀態:
1.Added: 對象為新對象,並且已添加到對象上下文,但尚未調用SaveChange之前都是Added(期間若修改對象屬性,對象狀態 任為Added, 刪除該對象時狀態變為Detached)
4.Modified: 當對象的屬性被修改時,如果 AutoDetectChangesEnabled=true,或者調用了DetectChanges(),那么該對象的狀態 會被修改為Modified
2.Deleted: 調用對象集合把對象A Remove后,EF標記該對象為准備從數據庫中刪除,調用SaveChanges()后數據庫刪除該記錄,
並且EF把該對象標記為Detached
3.Detached: 對象存在,但尚未被添加到上下文。
5.Unchanged: 當直接從數據庫加載到上下文,或者調用Attach附加一個對象時,該對象的狀態為Unchanged
狀態變化:
Added Update -》 Added
Added Save -》 Unchanged
Added Remove -》 Detached
Modified Update -》 Modified
Modified Save -》 Unchanged
Modified Remove -》 Deleted
Deleted Update -》 Deleted
Deleted Save -》 Detached
Deleted Add -》 Added(數據庫不會刪除原來的數據,並且會新增一條數據)
Unchanged Add -》 Added
Unchanged Update -》 Modified
Unchanged Save -》 Unchanged
Unchanged Remove -》 Deleted
Detached Update -》 Detached
Detached Add -》 Added
Detached Remove -》 出錯
OriginalValues:原先值,當對象附加或數據庫加載(不是添加,添加時只有當前值沒有原先值,添加后調用SaveChanges()才會有原先值)到上下文之后才有原先值。
1.對象被附加或者從數據庫中讀取到上下文時的值,SaveChanges()后的當前值與原先值保持一致。
CurrentValues:當前值,當對象上下文跟蹤之后才有當前值。
1.最新的值,即被修改后的最新值,如果值未被修改,那么當前值與原先值一樣。
ValidateOnSaveEnabled:保存前驗證對象的屬性最大最小長度等,默認為true。
1.如果ValidateOnSaveEnabled=true,那么SaveChanges()前不會調用DetectChanges(),
反之如果ValidateOnSaveEnabled=false,那么只有在AutoDetectChangesEnabled=true的情況下,
EF在SaveChanges()前才會調用DetectChanges()
AutoDetectChangesEnabled:自動跟蹤對象的屬性變化,默認為true。
1.如果關閉EF自動跟蹤,在SaveChanges()前尚未手動調用DetectChanges(),那么保存不會生效。(前提:對象狀態為Unchanged)
因為如果AutoDetectChangesEnabled=false,那么EF就不會自動跟蹤對象屬性的變化,從而導致對象的狀態也不會變為Modified,
並且因為AutoDetectChangesEnabled=false,那么EF在SaveChanges() 實際保存到數據庫之前不會調用DetectChanges(),
所以最終修改不會生效。
2.如果AutoDetectChangesEnabled=true,那么就算不調用DetectChanges(),EF在SaveChanges()時也能生效。
DetectChanges():同步對象與其屬性的狀態。
1.如果對象A的狀態為Unchanged,A的屬性A1狀態為Modified,那么調用DetectChanges()后,A狀態變為Modified
2.如果AutoDetectChangesEnabled=true,那么對象與其屬性的狀態會立即同步
AcceptAllChanges():上下文能跟蹤狀態為Added、Modified、Deleted的所有對象,修改他們的狀態為Unchanged。在SaveChanges()失敗時不 會調用該方法。
AcceptAllChangesAfterSave:標志SaveChanges()后調用AcceptAllChanges
1.EF6.0在SaveChanges()成功后始終會調用AcceptAllChanges(),把Added、Modified、Deleted的對象狀態修改為Unchanged
DetectChangesBeforeSave:標志在SaveChanges()前,需要調用DetectChanges()同步所有狀態
1.如果AutoDetectChangesEnabled=false,那么在SaveChanges()前,不會調用DetectChanges()同步所有狀態
SaveChanges():
1.只有當AutoDetectChangesEnabled=true,ValidateOnSaveEnabled=false的情況下,在保存之前才會調用DetectChanges()
2.當保存成功后,始終都會調用AcceptAllChanges()