Hier ist mein Modell von 3 Entitäten: Route, Location und LocationInRoute.
Die folgende Methode schlägt fehl und erhält beim Festschreiben eine Ausnahme:
public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations)
{
//Loop on locations and insert it without commit
InsertLocations(companyId, routesOrLocations);
RouteRepository routeRep = new RouteRepository();
Route route = routeRep.FindRoute(companyId, locations);
if (route == null)
{
route = new Route()
{
CompanyId = companyId,
IsDeleted = false
};
routeRep.Insert(route);
LocationInRouteRepository locInRouteRep = new LocationInRouteRepository();
for (int i = 0; i < locations.Count; i++)
{
locInRouteRep.Insert(new LocationInRoute()
{
//Id = i,
LocationId = locations[i].Id,
Order = i,
RouteId = route.Id
});
}
}
return route;
}
Dabei:
InsertRouteIfNotExists(companyId, locations);
UnitOfWork.Commit();
Ich habe:
Das Hauptende der Beziehung 'SimTaskModel.FK_T_STF_SUB_LOCATION_IN_ROUTE_T_STF_LOCATION_location_id' kann nicht ermittelt werden. Mehrere hinzugefügte Entitäten können denselben Primärschlüssel haben.
Beim Aufteilen des Commits und Einfügen in das Methos funktioniert es:
public static Route InsertRouteIfNotExists(Guid companyId, IListLocation> locations)
{
//Loop on locations and insert it without commit
InsertLocations(companyId, routesOrLocations);
UnitOfWork.Commit();
RouteRepository routeRep = new RouteRepository();
Route route = routeRep.FindRoute(companyId, locations);
if (route == null)
{
route = new Route()
{
CompanyId = companyId,
IsDeleted = false
};
routeRep.Insert(route);
LocationInRouteRepository locInRouteRep = new LocationInRouteRepository();
for (int i = 0; i < locations.Count; i++)
{
locInRouteRep.Insert(new LocationInRoute()
{
//Id = i,
LocationId = locations[i].Id,
Order = i,
RouteId = route.Id
});
}
UnitOfWork.Commit();
}
return route;
}
Ich möchte Commit einmal und außerhalb der Methode aufrufen. Warum schlägt es im ersten Beispiel fehl und was bedeutet diese Ausnahme?
c#
.net
entity-framework
Naor
quelle
quelle
Antworten:
Der Fehler wird durch eine Fremdschlüssel-ID (im Gegensatz zu einer Referenz) verursacht, die nicht behoben werden kann. In Ihrem Fall haben Sie eine LocationInRole, die auf einen Standort mit einer ID von 0 verweist. Es gibt mehrere Standorte mit dieser ID.
Den Standorten wurde noch keine ID zugewiesen, da sie zum Zeitpunkt der Generierung der ID noch nicht in der Datenbank gespeichert wurden. In Ihrem zweiten Beispiel werden die Standorte gespeichert, bevor auf ihre IDs zugegriffen wird. Deshalb funktioniert dies.
Sie können sich beim Definieren der Beziehungen nicht auf die Standort-IDs verlassen, wenn Sie SaveChanges erst später speichern möchten.
Tauschen Sie die folgende Zeile aus ...
...dafür...
Die Beziehungen basieren dann auf Objektreferenzen, die nicht von den LocationIDs abhängig sind.
quelle
Falls dies für zukünftige Leser von Nutzen ist, war dieser Fehler in meinem Fall auf einen falsch konfigurierten Fremdschlüssel in meiner Datenbank (und ein aus der Datenbank generiertes Modell) zurückzuführen.
Ich hatte Tische:
Parent (1-1) Child (1-many) Grandchild
und der Enkelkind-Tisch hatte versehentlich einen Fremdschlüssel bis zu seinem Elternteil (Kind) und seinem Großelternteil (Elternteil) erhalten. Beim Speichern mehrerer übergeordneter Entitäten aus neuen hat ich diesen Fehler erhalten. Fix war, den Fremdschlüssel zu korrigieren.
quelle
Nachdem ich auf denselben Fehler gestoßen bin, vermute ich sehr, dass das eigentliche Problem die Definition des Standorts war. Einfach gesagt, in EF Code First wette ich, dass es so aussah:
public class Location { public int Id { get; set; } ... public Location ParentLocation { get; set; } [ForeignKey("ParentLocation")] public int ParentLocationId { get; set; } }
Mit anderen Worten, in der Frage sind ParentLocation / ParentLocationId eine rekursive Referenz zurück zu dieser Tabelle.
Die ParentLocationId ist nicht nullbar. Das bedeutet, dass es mit einer 0 eingefügt wird und EF sich beim Einfügen beschwert, anstatt beim Migrieren - obwohl die Wahrheit ist, dass Sie nach dem Ausführen der Migration eine Tabelle haben, in die EF Sie niemals einfügen lässt.
Die einzige Möglichkeit, eine rekursive Referenz auf dieselbe Tabelle zurückzusetzen, besteht darin, die rekursive Referenz auf Null zu setzen:
public class Location { public int Id { get; set; } ... public Location ParentLocation { get; set; } [ForeignKey("ParentLocation")] public int? ParentLocationId { get; set; } }
Beachten Sie die
?
nach demint
.quelle
Für diejenigen, die nach dieser Ausnahme suchen:
In meinem Fall konnte keine erforderliche Navigationseigenschaft festgelegt werden.
public class Question { //... public int QuestionGridItemID { get; set; } public virtual QuestionGridItem GridItem { get; set; } //... public int? OtherQuestionID { get; set; } public Question OtherQuestion { get; set; } } //... question.OtherQuestion = otherQuestion; questionGridItem.Questions.Add(question); dataContext.SaveChanges(); //fails because otherQuestion wasn't added to //any grid item's Question collection
quelle
Ich hatte das gleiche Problem. mit unten Szenario für mich gelöst. Ich denke, Sie müssen Ihren Code wie folgt ändern:
var insertedRoute =routeRep.Insert(route); ..... insertedRoute.LocationInRoute = new List<LocationInRoute>(); for(....){ var lInRoute = new LocationInRoute(){ .... Route=insertedRoute; } insertedRoute.LocationInRoute.Add(lInRoute ); }
quelle