I started getting a new and horrifying Entity Framework error I had never seen before.
Conflicting changes detected. This may happen when trying to insert multiple entities with the same key.
It looked like it was due to me saving a parent and having it cascade to save children.
Soooo, I took it upon myself to save parent, save child, reconstitute relationship.
This was horrifying. My code went from Exhibit A:
///
/// Helper Method. Updates Sections and Items
///
/// Agenda ID
/// List of AgendaSections
/// The Current User creating Sections and Items
private void UpdateSectionsAndItems(int agendaId, IList<AgendaSection> agendaSections, IUser currentUser)
{
List<AgendaSectionItem> agendaSectionItems = new List<AgendaSectionItem>();
int sectionNumber = 0;
foreach (AgendaSection section in agendaSections)
{
section.Number = sectionNumber;
section.AgendaId = agendaId;
section.OwnerId = currentUser.UserId;
if (section.AgendaSectionItems != null)
{
int itemNumber = 0;
foreach (AgendaSectionItem item in section.AgendaSectionItems)
{
item.Number = itemNumber;
itemNumber++;
item.OwnerId = currentUser.UserId;
agendaSectionItems.AddRange(section.AgendaSectionItems);
}
}
sectionNumber++;
}
db.AgendaSections.AddRange(agendaSections);
db.AgendaSectionItems.AddRange(agendaSectionItems);
db.SaveChanges();
}
To the following horrifying monstrosity:
///
/// Helper Method. Updates Sections and Items
///
/// Agenda ID
/// List of AgendaSections
/// The current user
private void UpdateSectionsAndItems(int agendaId, IList<AgendaSection> agendaSections, IUser currentUser)
{
// This is a horrible workaround to deal with this mysterious error:
// Conflicting changes detected. This may happen when trying to insert multiple entities with the same key.
// That I get when I simply try to save parent (AgendaSection) and let it cascade down to the child (AgendaSectionItems).
IDictionary<int, List<AgendaSectionItem>> tempItemDictionary = new Dictionary<int, List<AgendaSectionItem>>();
int sectionNumber = 0;
foreach (AgendaSection section in agendaSections)
{
section.Number = sectionNumber;
section.AgendaId = agendaId;
if (section.AgendaSectionItems != null)
{
int itemNumber = 0;
foreach (AgendaSectionItem item in section.AgendaSectionItems)
{
item.Number = itemNumber;
itemNumber++;
item.OwnerId = currentUser.UserId;
if (tempItemDictionary.ContainsKey(section.Number.GetValueOrDefault()))
{
List<AgendaSectionItem> agendaSectionItems = tempItemDictionary[section.Number.GetValueOrDefault()];
agendaSectionItems.Add(item);
}
else
{
List<AgendaSectionItem> agendaSectionItems = new List<AgendaSectionItem>();
agendaSectionItems.Add(item);
tempItemDictionary.Add(section.Number.GetValueOrDefault(), agendaSectionItems);
}
}
}
// More workaround
section.AgendaSectionItems = null;
sectionNumber++;
}
db.AgendaSections.AddRange(agendaSections);
db.SaveChanges();
// More workaround ... FML
foreach (int i in tempItemDictionary.Keys)
{
IList<AgendaSectionItem> items = tempItemDictionary[i];
AgendaSection agendaSection = agendaSections.First(s => s.Number == i);
if (agendaSection != null)
{
foreach (AgendaSectionItem item in items)
{
item.SectionId = agendaSection.SectionId;
if (agendaSection.AgendaSectionItems == null)
{
agendaSection.AgendaSectionItems = new List<AgendaSectionItem>();
}
agendaSection.AgendaSectionItems.Add(item);
db.AgendaSectionItems.Add(item);
db.SaveChanges();
}
}
}
}
When I finally got down to it, what I had done was accidentally mapped my primary key on a table as a foreign key in a completely incorrect mapping. So, I went and rolled back the monstrosity and will sleep better tonight.
No comments:
Post a Comment