2014-01-26 57 views
12

DbSet<TEntity>.Add方法返回一個實體。我通常會預期Add操作有一個void返回類型。爲什麼DbSet Add會返回一個實體實例而不是void?

當我看EntityFramework source code,我看到了下面的實現:

public virtual TEntity Add(TEntity entity) 
    { 
     Check.NotNull(entity, "entity"); 

     GetInternalSetWithCheck("Add").Add(entity); 
     return entity; 
    } 

GetInternalSetWithCheck返回一個InternalSet<TEntity>

InternalSet<TEntity>Add方法,有趣的是在其簽名返回void類型:

public virtual void Add(object entity) 

我擔心的是我是否需要在修改與實體相關的實體以及添加到DbSet時要小心。

E.g.有沒有情況

var entity = new MyEntity(); 
_dbSet.Add(entity); 
entity.SomeDatModifyingMethod(); 
_dbContext.SaveChanges(); 

可能給不同的行爲比

var entity = new MyEntity(); 
entity.SomeDatModifyingMethod(); 
_dbSet.Add(entity); 
_dbContext.SaveChanges(); 

或不同的行爲:

var entity = new MyEntity(); 
entity = _dbSet.Add(entity); 
entity.SomeDatModifyingMethod(); 
_dbContext.SaveChanges(); 

在基本的默認實現,它不會永遠的事,因爲它只是總是返回完全相同的實例。然而,Add方法是virtual,所以它可以被覆蓋(雖然在公共源代碼中,唯一的覆蓋是測試加倍 - 但我不確定源代碼實際上是否包含例如SqlServer支持實現)。

爲什麼DbSet Add返回實體實例而不是void?

回答

4

TEntity是引用類型,所以什麼被添加到InternalSet<T>將是一個參考的實體,而不是價值。在將實體內容添加到集合之前或之後更改其內容無關緊要,因爲它從未在數據庫中創建。無論如何,將會執行INSERT或等效。

至於爲什麼Add回報TEntity,它希望它的,因爲它允許類似的事情:

_dbSet.Add(new MyEntity()).SomeDatModifyingMethod(); 
_dbContext.SaveChanges(); 
+0

這主要是有道理的 - 只要'Add'方法永遠不會像返回一個代理那樣 - 可能用於更改跟蹤? - 在這種情況下,添加後重新分配參考可能很重要? (例如,最後一個代碼示例) – Nathan

+0

雖然想到了它,但我不知道爲什麼你需要更改跟蹤一個新增的實體... – Nathan

+0

'Add'可能不是'SaveChanges '。如果有'刪除'呢? –

6

它可以讓你寫一個「查找或添加」模式

var person = context.People.Find(ssn) ?? context.People.Add(new Person 
{ 
    SocialSecurityNumber = ssn, 
    FirstName = "John", 
    LastName = "Doe" 
}); 
相關問題