我有一个显示实体列表的窗口,我想在新窗口中编辑gridview的选择项(不在网格中)。当我提交表单时没有发生错误,但实体在数据库中没有变化!请帮帮我。
在我的列表窗口代码后面:
private ObservableCollection<Employee> AllEmployeesData { get; set; }
private ListCollectionView View;
并在window_loaded中使用此方法获取数据:
public void LoadAllEmployees()
{
IEnumerable<Employee> data = null;
using (ArchiveEntities db = new ArchiveEntities())
{
data = db.Employees.Include("Department");
this.AllEmployeesData = new ObservableCollection<Employee>(data);
}
CollectionViewSource employeeSource = (CollectionViewSource)this.FindResource("AllEmployeesDataSource");
employeeSource.Source = this.AllEmployeesData;
this.View = (ListCollectionView)employeeSource.View;
}
编辑按钮点击事件:
EditEmployeeView win = new EditEmployeeView();
View.EditItem(SelectedEmployee);
win.DataContext = SelectedEmployee;
if ((bool)win.ShowDialog())
{
using (ArchiveEntities db = new ArchiveEntities())
{
Employee employee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
db.Employees.ApplyCurrentValues(employee);
db.SaveChanges();
View.CommitEdit();
}
}
else
{
View.CancelEdit();
}
以上所有代码都在我的第一个窗口中(显示实体列表的窗口)。 在我的第二个窗口(用于编辑第一个窗口的选定项目的窗口)中:
提交按钮点击事件:
DialogResult = true;
Close();
我的问题是:当我提交编辑表单时没有发生错误但数据不保存在数据库中,当我取消编辑表单时,我收到此错误:
InvalidOperationException未处理:不支持CancelEdit 对于当前的编辑项目。
答案 0 :(得分:1)
为什么使用View.EditItem,View.CommitEdit和View.CancelEdit?你需要的只是你的win.DataContext = SelectedEmployee。我没有得到的是你将新的编辑数据设置到你的实体?
using (ArchiveEntities db = new ArchiveEntities())
{
Employee employee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
db.Employees.ApplyCurrentValues(employee);
db.SaveChanges();
View.CommitEdit();
}
您从db获得了员工,但您没有将SelectedEmployee中编辑的数据应用于您的员工。还是我错过了什么?
SelectedEmployee是您的数据库中的实体
data = db.Employees.Include("Department");
this.AllEmployeesData = new ObservableCollection<Employee>(data);
那么为什么你不使用它并将其保存回db?
db.SaveChanges(SelectedEmployee );
答案 1 :(得分:1)
远离datacontext中的“using”对于实体框架来说是一个非常糟糕的方法!
如果在保存之前关闭了datacontext,则所有实体结果都将断开连接,并保存为no resut。
尝试这种方式,使用类级别上下文,保持连接并使用entityframework的所有功能
public mainClass{
private ArchiveEntities db;
private ObservableCollection<Employee> allEmployeesData;
private Employee selctedEmplyee;
// property in binding
public ObservableCollection<Employee> AllEmployeesData { get{return allEmployeesData;} set{allEmployeesData=value; onPropertyChanged("AllEmployeesData"); }
public Employee SelctedEmplyee { get{return selctedEmplyee;} set{selctedEmplyee=value; onPropertyChanged("SelctedEmplyee"); }
mainWindow (){ //Constructor
db=new ArchiveEntities();
}
private void onedit(){
new detailWindow(SelectedEmployee).ShowDialog();
//reload from db, upadte current element if modified in the detail window
SelectedEmployee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
}
//no need to save in main window (is only for view)
}
public class detailWindow(){
private ArchiveEntities db;
private Employee selctedEmplyee;
//employee to modify
public Employee SelctedEmplyee { get{return selctedEmplyee;} set{selctedEmplyee=value; onPropertyChanged("SelctedEmplyee"); }
public detailWindow(Employee SelectedEmployee){
db=new ArchiveEntities; // a new indipendent context
SelectedEmployee = db.Employees.Single(x => x.Id == SelectedEmployee.Id);
}
public void onSave(){
db.SaveChanges(); //effect only in SelectedEmployee
// if you don'save main window data will not change
}
}
答案 2 :(得分:0)
Employee类必须实现IEditableObject 你可以在这里看到一个例子:https://msdn.microsoft.com/en-us/library/system.componentmodel.ieditableobject.aspx 在此实现之后,它应该按预期工作