2017-03-02 131 views
1

我在我的應用程序中使用EF數據庫優先模型。這是WPF MVVM應用程序,所以我使用長時間生活的DbContext,它在應用程序啓動時創建並在完成時處理。實體框架6使用另一個記錄的值更新現有記錄

有兩個表 - clientssettingssettings將所有客戶端的設置存儲爲client_id作爲外鍵,settings_id作爲主鍵。 在這settings表我有一些'默認'記錄settings_id=1client_id=1。我希望我的應用程序通過按下按鈕來恢復客戶端的「默認」設置。

以我vewmodel我有Client類型,這是我的分貝實體模型類的ObservableCollection,並Client類型的屬性SelectedClient,綁定到當前選定的客戶機(在一些列表框)。我也有實體類Settings,其中有一些字段代表設置表中的不同設置。我想從'默認'記錄中的所有這些設置來替換當前選定的客戶端設置。

我做那麼什麼是:

public void OnResetClientSettingsCommandExecute() 
    { 
     var defaultSettings = Global.DbContext.Settings.FirstOrDefault(c => c.client_id == 1); 
     if (defaultSettings == null) return; 

     var tmp = defaultSettings; 
     tmp.client_id = SelectedClient.client_id; // doing this to change the only field which needs to remain untouched    
     var selectedClientSettings = Global.DbContext.Settings.FirstOrDefault(c => c.client_id == SelectedClient.client_id); 
     selectedClientSettings = tmp; 

     Global.DbContext.SaveChanges(); 

    } 

此代碼不能在所有的工作。我唯一得到的 - 在settingsSelectedClient的client_id處將我的'默認'記錄更改爲client_id。我不知道爲什麼會發生,我想如果我使用tmp它會好的,但不會。 我知道有一些做法使用Attach()方法或更改實體的StateModified - 我試過所有這些,沒有人爲我工作,我想因爲我使用長壽DbContext方法。我很困惑在我的應用程序中更新記錄 - 我只是不能這樣做,DbContext.SaveChanges()方法不保存對數據庫的更改,但由於某種原因將它們回滾。所以我必須使用原始的SQL查詢,這是一個石器時代。

請別人幫我弄清楚我做錯了什麼。謝謝。

+0

你想在你的數據庫中創建另一行的默認設置值,並鏈接到選定的客戶端ID嗎? – dbraillon

+0

不,我已經有了一條線,我想用默認的字段替換它的所有字段,除了client_id字段 –

+1

正如你應該注意到的那樣,你不能像你這樣做。 'var tmp = defaultSettings;'不會創建一個新的對象,它只會創建一個新的對已經存在的對象的引用。 – dbraillon

回答

1

您可以創建一個方法的類像這樣

public static void CopyValues<T>(T source, T destination) 
{ 
    var props = typeof(T).GetProperties(); 

    foreach(var prop in props) 
    { 
     var value = prop.GetValue(source); 
     prop.SetValue(destination, value); 
    } 
} 

然後指定你的鑰匙臨時變量,複製性的休息和重新分配你的鑰匙到其原始值。

int id = selectedClientSettings.client_id; 
ObjectCopier.CopyValues<Client>(defaultSettings, selectedClientSettings); 
selectedClientSettings.client_id = id; 
+0

這正是我一直在尋找的東西,但現在它引發了一個exceptiopn,因爲它試圖複製主鍵。我怎麼修改這個跳過複製主鍵'settings_id'從默認設置到選定的客戶端設置? –

+0

如果你可以編程的方式找到你的主鍵屬性,你可以在foreach循環中添加一些邏輯來跳過該屬性。 –

1

正確的做法。但它很累!

public void OnResetClientSettingsCommandExecute() 
{ 
    var defaultSettings = Global.DbContext.Settings.FirstOrDefault(c => c.client_id == 1); 
    if (defaultSettings == null) return; 

    var selectedClientSettings = Global.DbContext.Settings.FirstOrDefault(c => c.client_id == SelectedClient.client_id); 
    selectedClientSettings.serviceName = defaultSettings.serviceName; 
    selectedClientSettings.write_delay = defaultSettings.write_delay; 
    // etc... 

    Global.DbContext.SaveChanges(); 
} 

您應該考慮使用AutoMapper,它可能會更容易編寫。

相關問題