2010-11-05 2 views
18

Zunächst einmal gibt es keine Chance, dass dies ein Multi-User-Problem ist, da ich lokal auf einer dev-Version der Datenbank arbeite.Zeile nicht gefunden oder geändert LINQ C# Fehler auf einfache Anweisung

Ich bekomme den nicht sehr erklärenden Row not found or changed Fehler geworfen, wenn ich db.SubmitChanges() ausführen. Wenn ich die Ausführung unterbricht, bevor die SubmitChanges() auftritt, kann ich in SQL Server Management Studio einchecken, und die Zeile existiert vorhanden!

Hier ist der Code für die gesamte Funktion, nur um es in Kontext für jeden, der helfen möchte, zu setzen, aber die Problemlinie ist direkt am Ende (Zeile 48).

Aktualisieren Dies ist ein wirklich seltsames: Der Fehler wird durch Aktualisieren von MatchingTrans.Url (siehe vorletzte Zeile des Codes) verursacht. Wenn Sie diese Zeile auskommentieren, wird der Fehler nicht ausgegeben - selbst wenn das MatchingTrans.Title noch aktualisiert wird.

private static void MenuItemUpdate(int languageId, NavigationItem item) 
{ 
    using (var db = DataContextFactory.Create<MyDataContext>()) 
    { 
     // Select existing menu item from database. 
     var dbItem = 
      (from i in db.MenuItems 
      where i.Id == item.Id 
      select i).Single(); 
     // Obtain ID of link type. 
     dbItem.FkLinkTypeId = GetLinkTypeByName(
      Enum.GetName(typeof (NavigationItemLinkType), item.LinkType)).Id; 
     // Update the Link field with what is given. 
     dbItem.Link = item.Link; 
     db.SubmitChanges(); 

     // Item already exists and needs editing. 
     // Get associated translations. 
     var trans = 
      from t in db.MenuItemTranslations 
      where t.FkMenuItemId == item.Id 
      select t; 

     // If translation exists for given language, edit it. 
     var matchingTrans = 
      (from t in trans 
      where t.FkLanguageId == languageId 
      select t).SingleOrDefault(); 

     if (matchingTrans == null) 
     { 
      // No matching translation - add one. 
      var newDbTrans = new MenuItemTranslation 
      { 
       FkMenuItemId = item.Id, 
       FkLanguageId = languageId, 
       Title = item.Title, 
       Url = item.FriendlyUrl 
      }; 
      db.MenuItemTranslations.InsertOnSubmit(newDbTrans); 
      db.SubmitChanges(); 
     } 
     else 
     { 
      // Matching translation - edit it. 
      matchingTrans.Title = item.Title; 
      matchingTrans.Url = item.FriendlyUrl; 
      db.SubmitChanges(); 
      // WTF ERROR: Row not found or changed. 
     } 
    } 
} 
+0

Haben Sie SQL Profiler? Wenn ja, würde ich mir ansehen, was SQL tatsächlich in der DB ausführt und was die DB daraus macht. Was ist der Primärschlüssel in MenuItemTranslations? –

+0

@Ian Griffiths Danke für die Info, ich werde einen Blick auf SQL Profiler werfen. Der Primärschlüssel ist übrigens Id. – Greg

Antwort

47

Mit Blick auf die SQL Profiler-Ausgabe hat es mir geholfen, die Antwort darauf zu finden. Es wurde ein schlechtes Stück SQL erzeugt, das mit WHERE 0 = 1 endete ... ein offensichtlicher Fehler.

Es stellt sich heraus, dass das Feld einfach geändert wurde, um Nullen von einem anderen Entwickler zuzulassen, und die Linq-to-SQL-Datei wurde nicht entsprechend aktualisiert.

Kurz gesagt, wenn die Row not found or changed Fehlermeldung ohne Grund erzeugt zu sein scheint, stellen Sie sicher, Ihre Datenbank-Schema genau entspricht Ihrer .dbml Datei sonst werden Sie diese Fehlermeldung auf alle Felder erhalten, die leicht Schemata unterscheiden haben.

+3

Sie sollten dies als die Antwort markieren, sonst werden Leute, die nach unbeantworteten Fragen suchen, hierher kommen, um zu helfen, nur um zu erkennen, dass Sie das Problem bereits gelöst haben ... –

+4

Ich hatte gerade das gleiche Problem, außer dass ich der dumme Entwickler war Das änderte die Eigenschaft "allow null", erlaubte mir, abgelenkt zu werden und erkannte, dass ich vergessen hatte, mein Modell zu aktualisieren. – dotnetnewb

+2

Für mich wurde das Schema mit datetime und der Datenbankspalte mit Datum erstellt ... – Dragouf

3

Werfen Sie einen Blick auf die Verbindungseigenschaft "No Count" auf SQL Server-Server-Ebene

1. Rechtsklick auf SQL Server-Verbindung im Objekt-Explorer -> Property
2. Gehen Sie zu Registerkarte Verbindung/Seite
3. Suchen Sie nach der Standardverbindungsoption "no count"
4. Stellen Sie sicher, dass diese Option nicht aktiviert ist.

1

Ich hatte dieses Problem, auch wenn das Datenbankschema und dbml genau übereinstimmten. Das Problem war, dass ich versuchte, eine Entität zu ändern und Entitäten in eine einzige SubmitChanges-Anweisung einzufügen. Ich habe es behoben, indem ich SubmitChanges für jede Operation statt für alle gleichzeitig vorgenommen habe.

Das war alles in einem Transaktionsbereich, so dass etwas damit zu tun haben kann, aber ich bin mir nicht sicher.

2

Eine andere Möglichkeit, die ich gefunden habe, hier die hervorragende Liste von Antworten hinzuzufügen:

Wenn eine nicht-Nullable-Spalte in einer Datenbank mit - dann, dass ein Datentyp zuordnen, die intrinsisch nullable (in diesem Beispiel ist Der DB-Typ ist LONG BLOB NOT NULL, der einem Byte-Array in C# zugeordnet ist. Sie können in einer Situation landen, in der das Aktualisieren der Datenbank mit genau demselben Byte-Array dazu führt, dass dieser Fehler ausgelöst wird.

Beispiel: Sie haben eine Website, auf der der Benutzer ein Bild in die Datenbank hochladen kann. Ihre Tabelle hat einen Blob (Bild im SQL-Server, was auch immer), der nicht nullfähig ist. Der Benutzer wählt, den Datensatz mit dem exakt gleichen Bild zu aktualisieren, das bereits vorhanden ist. Die Aktualisierungsprüfung schlägt fehl. Ich habe das behoben, indem ich zunächst eine .SequenceEqual() - Prüfung durchführte und dann nur .SubmitChanges() für das Kontextobjekt aufruft, wenn das eingehende Byte-Array nicht dem vorhandenen Byte-Array entsprach.

Verwandte Themen