2012-05-28 84 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; 
}