Ho una relazione molti-a-molti tra Issues
e Scopes
nel mio contesto EF. In ASP.NET MVC, viene visualizzato un modulo Modifica che consente all'utente di modificare un determinato problema. Nella parte inferiore del modulo, è presente un elenco di caselle di controllo che consentono loro di selezionare quali ambiti si applicano a questo problema. Quando si modifica un problema, probabilmente avrà sempre alcuni ambiti associati - le caselle saranno già controllate. Tuttavia, l'utente ha la possibilità di controllare più ambiti o rimuovere alcuni degli ambiti correntemente controllati. Il mio codice sembrava qualcosa di simile per salvare solo il problema:Entity Framework Update Entità insieme alle entità figlio (aggiungere/aggiornare se necessario)
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);
}
}
Così, quando provo ad aggiungere nella logica di salvare l'scopi associato, ho provato diverse cose, ma alla fine, questo è ciò che ha reso il più senso per me:
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);
}
}
Ma, purtroppo, che getta solo la seguente eccezione:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
che cosa sto facendo di sbagliato?
Perfetto! E guardando SQL profiler, è solo una chiamata "extra" al DB per .Load(), ma molto più pulito di aggiungere/rimuovere rispetto al modo in cui lo usavo a mano con le stored procedure. Grazie! – Jorin
James bella risposta. Questo è un problema comune in molte applicazioni (aggiungere/rimuovere i tag in modo efficace). Non è ora che una funzione a livello di sistema esegua questa operazione senza uno schermo pieno di codice? Qualcosa come * issue.Scopes.ReplaceWith (myScopes); * – TFD
@TFD sì, ti sento. In caso contrario, la squadra EF ha molto da offrire, un semplice metodo di estensione potrebbe fare il trucco anche se giusto? –