作为我之前question的后续内容,我现在知道EF不会自动为我保存整个实体的所有更改。如果我的实体有List< Foo>,我需要更新该列表并保存。但是怎么样?我尝试过一些东西,但我无法正确保存列表。
我在Application和CustomVariableGroup之间有多对多的关联。应用可以包含一个或多个组,一个组可以属于一个或多个应用。我相信我已经使用Code First实现正确设置了这个,因为我在数据库中看到了多对多关联表。
底线是Application类有一个List< CustomVariableGroup>。我的简单案例是应用程序已经存在,现在用户已经选择了一个属于该应用程序的组。我想在DB中保存该更改。
尝试#1
this.Database.Entry(application).State = System.Data.EntityState.Modified;
this.Database.SaveChanges();
结果:关联表仍然没有行。
尝试#2
this.Database.Applications.Attach(application);
var entry = this.Database.Entry(application);
entry.CurrentValues.SetValues(application);
this.Database.SaveChanges();
结果:关联表仍然没有行。
尝试#3
CustomVariableGroup group = application.CustomVariableGroups[0];
application.CustomVariableGroups.Clear();
application.CustomVariableGroups.Add(group);
this.Database.SaveChanges();
结果:关联表仍然没有行。
我已经研究了很多,我尝试了比我演示的更多的东西,而我根本不知道如何使用新的CustomVariableGroup更新应用程序列表。应该怎么做?
编辑(解决方案)
经过数小时的反复试验,这似乎有效。看来我需要从数据库中获取对象,修改它们,然后保存它们。
public void Save(Application application)
{
Application appFromDb = this.Database.Applications.Single(
x => x.Id == application.Id);
CustomVariableGroup groupFromDb = this.Database.CustomVariableGroups.Single(
x => x.Id == 1);
appFromDb.CustomVariableGroups.Add(groupFromDb);
this.Database.SaveChanges();
}
答案 0 :(得分:0)
虽然我认为这有点像黑客,但它确实有效。我发布这篇文章是为了帮助其他人节省一整天的工作量。
public void Save(Application incomingApp)
{
if (incomingApp == null) { throw new ArgumentNullException("incomingApp"); }
int[] groupIds = GetGroupIds(incomingApp);
Application appToSave;
if (incomingApp.IdForEf == 0) // New app
{
appToSave = incomingApp;
// Clear groups, otherwise new groups will be added to the groups table.
appToSave.CustomVariableGroups.Clear();
this.Database.Applications.Add(appToSave);
}
else
{
appToSave = this.Database.Applications
.Include(x => x.CustomVariableGroups)
.Single(x => x.IdForEf == incomingApp.IdForEf);
}
AddGroupsToApp(groupIds, appToSave);
this.Database.SaveChanges();
}
private void AddGroupsToApp(int[] groupIds, Application app)
{
app.CustomVariableGroups.Clear();
List<CustomVariableGroup> groupsFromDb2 =
this.Database.CustomVariableGroups.Where(g => groupIds.Contains(g.IdForEf)).ToList();
foreach (CustomVariableGroup group in groupsFromDb2)
{
app.CustomVariableGroups.Add(group);
}
}
private static int[] GetGroupIds(Application application)
{
int[] groupIds = new int[application.CustomVariableGroups.Count];
int i = 0;
foreach (CustomVariableGroup group in application.CustomVariableGroups)
{
groupIds[i] = group.IdForEf;
i++;
}
return groupIds;
}