Tengo una relación de varios a varios entre Issues
y Scopes
en mi contexto de EF. En ASP.NET MVC, aparece un formulario de edición que permite al usuario editar un problema en particular. En la parte inferior del formulario, hay una lista de casillas de verificación que les permite seleccionar qué ámbitos se aplican a este problema. Al editar un problema, es probable que siempre tenga algunos ámbitos asociados con él: estos cuadros ya se verán. Sin embargo, el usuario tiene la oportunidad de verificar más ámbitos o eliminar algunos de los ámbitos controlados actualmente. Mi código se veía algo como esto para salvar sólo el tema de:Entidad de actualización de Entity Framework junto con entidades secundarias (agregar/actualizar según sea necesario)
using (var edmx = new MayflyEntities())
{
Issue issue = new Issue { IssueID = id, TSColumn = formIssue.TSColumn };
edmx.Issues.Attach(issue);
UpdateModel(issue);
if (ModelState.IsValid)
{
//if (edmx.SaveChanges() != 1) throw new Exception("Unknown error. Please try again.");
edmx.SaveChanges();
TempData["message"] = string.Format("Issue #{0} successfully modified.", id);
}
}
lo tanto, cuando intento agregar en la lógica de salvar la alcances asociado, he intentado varias cosas, pero en última instancia, esto es lo que hizo el más sentido para mí:
using (var edmx = new MayflyEntities())
{
Issue issue = new Issue { IssueID = id, TSColumn = formIssue.TSColumn };
edmx.Issues.Attach(issue);
UpdateModel(issue);
foreach (int scopeID in formIssue.ScopeIDs)
{
var thisScope = new Scope { ID = scopeID };
edmx.Scopes.Attach(thisScope);
thisScope.ProjectID = formIssue.ProjectID;
if (issue.Scopes.Contains(thisScope))
{
issue.Scopes.Attach(thisScope); //the scope already exists
}
else
{
issue.Scopes.Add(thisScope); // the scope needs to be added
}
}
if (ModelState.IsValid)
{
//if (edmx.SaveChanges() != 1) throw new Exception("Unknown error. Please try again.");
edmx.SaveChanges();
TempData["message"] = string.Format("Issue #{0} successfully modified.", id);
}
}
Pero, por desgracia, que acaba de lanza la siguiente excepción:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
¿Qué estoy haciendo mal?
¡Eso es perfecto! Y mirando SQL Profiler, es solo una llamada "extra" al DB para .Load(), pero una manera mucho más limpia de agregar/eliminar que la forma en que solía hacerlo a mano con procedimientos almacenados. ¡Gracias! – Jorin
James buena respuesta. Este es un problema común en muchas aplicaciones (efectivamente agregar/eliminar etiquetas). ¿No es hora de que una función de nivel del sistema haga esto sin una pantalla llena de código? Algo así como * issue.Scopes.ReplaceWith (myScopes); * – TFD
@TFD, sí, te escucho. En su defecto, el equipo de EF tiene muchos en su plato, un método de extensión simple haría el truco, ¿verdad? –