2017-03-02 73 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,它可能会更容易编写。

相关问题