2012-05-28 85 views
0

作为我早期的question的后续,我现在知道EF不会自动为我保存整个实体的所有更改。如果我的实体有一个名单<Foo>,我需要更新该列表并保存它。但是如何?我已经尝试了一些东西,但无法正确保存列表。实体框架4.3 - 代码优先 - 更新列表属性

我有一个应用程序和CustomVariableGroup之间的多对多关联。一个应用可以有一个或多个组,并且一个组可以属于一个或多个应用。我相信在Code First实现中我已经正确设置了它,因为我看到了DB中的多对多关联表。

底线是应用程序类有一个列表<CustomVariableGroup>。我的简单情况是该应用程序已经存在,现在用户已经选择了一个属于该应用程序的组。我想在数据库中保存更改。

尝试#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更新应用程序的列表。应该怎么做?

EDIT(解决方案)

经过试验和错误的时间,这似乎是工作。看来我需要从数据库中获取对象,修改它们,然后保存它们。

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

虽然我认为这有点黑客,但它的工作原理。我发布这篇文章的目的是为了帮助其他人节省一整天的工作量。

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; 
}