我在我的应用中使用EF数据库优先模型。它是WPF MVVM应用程序,所以我使用长寿命的DbContext,它是在应用程序启动时创建的,并在完成时处理。
有两个表格 - clients
和settings
。 settings
将所有客户端的设置存储为client_id
作为外键,settings_id
作为主键。
在此settings
表格中,我有settings_id=1
和client_id=1
的“默认”记录。我希望我的应用程序通过按下按钮来恢复客户端的“默认”设置。
在我的vewmodel中,我有一个ObservableCollection
类型Client
,它是我的数据库实体模型类,属性SelectedClient
类型为Client
,绑定到当前选中客户端(在一些ListBox中)。我还有实体类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();
}
此代码根本不起作用。我唯一能做到的就是将client_id
更改为settings
中的{默认'记录到SelectedClient
的client_id。我不知道为什么会发生这种情况,我想如果我会使用tmp
它会没问题,但不会。
我知道有一些使用Attach()
方法或将实体的State
更改为Modified
的做法 - 我尝试了所有这些方法而没有人为我工作,我想因为我使用长寿DbContext做法。
老实说,我对我的应用程序中的记录更新感到非常困惑 - 我只是不能这样做,DbContext.SaveChanges()方法不保存对数据库的更改,但由于某种原因将它们回滚。所以我必须使用原始的SQL查询,这有点像石器时代。
请有人帮我弄清楚我做错了什么。感谢。
答案 0 :(得分:2)
你可以用这样的方法创建一个类
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;
答案 1 :(得分: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,它可能更容易编写。