2014-03-07 62 views
1

有沒有保存實體而不保存導航屬性的優雅方式?在不保存導航屬性的情況下保存EF實體

我從網頁發送實體圖到Web API服務。由於客戶端無法訪問導航屬性,因此它將沒有這些屬性的數據發送回服務器。一旦我將該實體標記爲State.Modified,EF也會嘗試保存關係。

我要去嘗試以下工作流程,但不很喜歡:

  1. 加載原始實體從數據庫
  2. 創建通用的方法來複制所有非導航屬性從修改原始實體
  3. 屬性與Id結尾的名字將不會被複制(因爲我有外國鍵也映射)
  4. 保存這樣的實體

這不是很優雅。你會怎麼做?

+0

映射庫與AutoMapper類似,默認情況下,它只映射公共屬性?你也可以創建一般規則(認爲你可以做一些事情,「不要以ID結尾的屬性」)。 –

+0

這是目前的想法。我想問的是,有沒有辦法告訴EF不要保存它們,或者讓EF處理這個問題。如果沒有,那麼你給了我答案。我會再多等一下,看看是否有其他想法 –

回答

0

這不是很優雅。你會怎麼做?

我會寫的東西自動地作品箱子。我不喜歡automapping要麼。

所以我最終會手動做的事情:

public User UpdateUser(User updatedUser) 
{ 
    // Gets the original entity 
    var dbUser = this.context.Users.SingleOrDefault(z => z.Id == updatedUser.Id); 
    if (dbUser == null) 
    { 
     // Exception here 
    } 

    // Manually update ONLY properties that can be updated through UpdateUser 
    dbUser.Name = updatedUser.Name; 
    dbUser.FirstName = updatedUser.FirstName; 
    ... 

    // Saves the context 
    this.context.SaveChanges(); 

    // Returns updated entity 
    return dbUser; 
} 

更安全,以依賴調用您的服務或基於屬性名的規則的層上,以確保屬性可以是否更新。

例如,在上述情況下,如果您有專門的ChangePassword服務,則可以假定您不想更新User.PasswordHash屬性。

+0

我沒有在automapper中看到任何魔術,並且當我寫一個代碼時不想寫20行代碼。但這只是另一個觀點;) –

+0

@RaphaëlAlthaus是的,沒有什麼魔力,但是內部完成的內容過於抽象,尤其是當您添加特定的映射規則時。其他問題是,犯錯很容易。想象一下你爲'User'實體添加一個名爲'UserCreationDate'的新屬性的情況。你真的不想在'UpdateUser'服務中更新它。如果你不告訴他做別的事情,那會是因爲automapper。我更喜歡添加一段代碼來完成_something new_,而不是添加一段代碼來阻止另一段代碼做某件事。 – ken2k

+0

我原則上同意肯,然而我認爲這是首席工程師的一次責任並且釋放其他責任。我知道我不應該允許任何人向屬性或相關實體注入價值,所以我想知道你對我目前所做的事情的看法。我有一個具有以下簽名的方法:void ApplyDbGraphChanges (entity)',它對給定實體應用更改並遍歷與提供的類型('T1','T2', ..)。當然,也有非泛型方法和泛型參數少的方法。 –

相關問題