我在数据库中更新现有讲师的数据挣扎。
每个讲师具有由他教名 ,AcademicDegree和课程 /她( 课程==教训 )。
事实上,有更多的性能class Lecturer
,但他们是不相关的。 为简单起见让我们假设POCO类的定义是这样的:
// POCO class (Entity Framework Reverse Engineering Code First)
public class Lecturer
{
public Lecturer()
{
this.Courses = new List<Course>();
}
public int Id_Lecturer { get; set; } // Primary Key
public string Name { get; set; }
public int? Academic_Degree_Id { get; set; }
public virtual AcademicDegree AcademicDegree { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
在数据访问层我有方法void UpdateLecturer(Lecturer lecturer)
,其应该更新其讲师Id_Lecturer
等于lecturer.Id_Lecturer
(使用lecturer.Name
, lecturer.AcademicDegree
和lecturer.Courses
)。
这是非常方便的方法,因为在视图模型我可以调用_dataAccess.UpdateLecturer(SelectedLecturer)
其中SelectedLecturer
在绑定XAML ; SelectedLecturer
属性可以通过用户在设置TextBox
ES和Checkbox
)。
可惜的是这种方法:
public void UpdateLecturer(Lecturer lecturer)
{
using(var db = new AcademicTimetableDbContext())
{
// Find lecturer with Primary Key set to 'lecturer.Id_Lecturer':
var lect = db.Lecturers.Find(lecturer.Id_Lecturer);
// If not found:
if (lect == null)
return;
// Copy all possible properties:
db.Entry(lect).CurrentValues.SetValues(lecturer);
// Everything was copied except 'Courses'. Why?!
// I tried to add this, but it doesn't help:
// var stateMgr = (db as IObjectContextAdapter).ObjectContext.ObjectStateManager;
// var stateEntry = stateMgr.GetObjectStateEntry(lect);
// stateEntry.SetModified();
db.SaveChanges();
}
}
更新一切(即Id_Lecturer
, Name
, Academic_Degree_Id
和AcademicDegree
除外 ) Courses
这之后是不变db.SaveChanges()
为什么? 我怎样才能解决这个问题?
类似的问题:
- 更新-AN-实体在实体框架
- 怎么办,可以-I连接-A-实体框架对象-也就是说,未启用,来自该数据库
- 使用-的DbContext式-EF-特征CTP5部分-4-附加附接和-实体- states.aspx
- 实体框架更新管理与相关实体
- 实体框架代码先无装卸方法-上的DbContext
-编辑-
我也试过这样(的想法来自这个职位 ):
public void UpdateLecturer(Lecturer lecturer)
{
using (var db = new AcademicTimetableDbContext())
{
if (lecturer == null)
return;
DbEntityEntry<Lecturer> entry = db.Entry(lecturer);
if (entry.State == EntityState.Detached)
{
Lecturer attachedEntity = db.Set<Lecturer>().Find(lecturer.Id_Lecturer);
if (attachedEntity == null)
entry.State = EntityState.Modified;
else
db.Entry(attachedEntity).CurrentValues.SetValues(lecturer);
}
db.SaveChanges();
}
}
但仍然课程不覆盖旧值。
- 编辑2 -
响应于该问题@Slauma我将描述我如何装载SelectedLecturer
(其被传递到UpdateLecturer(Lecturer lecturer)
方法作为一个参数)。
我执行MVVM的概念,所以我有我的解决方案中查看项目, DataContext
设置为LecturerListViewModel
。 在查看有DataGrid
与DATABSE获取所有讲师名单。 DataGrid
的绑定是这样的:
<DataGrid AutoGenerateColumns="False" Name="LecturersDataGrid" HeadersVisibility="Column" IsReadOnly="True" ItemsSource="{Binding Lecturers,Mode=TwoWay}" SelectedItem="{Binding SelectedLecturer, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="Academic degree" Binding="{Binding AcademicDegree.Degree_Name}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Edit" Click="EditButtonClick"/>
<Button Content="Delete" Command="{Binding DataContext.RemoveLecturer, ElementName=LecturersDataGrid}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Lecturers
是从数据库中提取中LecturerListViewModel
这样的构造函数:
///
/// Code within LecturerListViewModel class:
///
// All lecturers from database.
public ObservableCollection<Lecturer> Lecturers
// Constructor
public LecturerListViewModel()
{
// Call to Data Access Layer:
Lecturers = new ObservableCollection<Lecturer>(_dataAccess.GetAllLecturers());
// Some other stuff here...
}
private Lecturer _selectedLecturer;
// Currently selected row with lecturer.
public Lecturer SelectedLecturer
{
get { return _selectedLecturer; }
set { SetProperty(out _selectedLecturer, value, x => x.SelectedLecturer); }
}
///
/// Data Access Layer (within DataAccess class):
///
public IEnumerable<Lecturer> GetAllLecturers()
{
using (var dbb = new AcademicTimetableDbContext())
{
var query = from b
in dbb.Lecturers.Include(l => l.AcademicDegree).Include(l => l.Timetables).Include(l => l.Courses)
select b;
return query.ToList();
}
}