2016-08-09 253 views
0

Ich habe eine ziemlich einfache Tabelle in SQL Server (Doppelschlüssel, keine Fremdschlüssel). Ich habe Mapping-Code mit SQLMetal generiert. Ich habe auch die automatisch generierte Teilklasse erweitert, damit ich IEquatable implementieren kann. Das Problem ist, dass ich sobald ich IEquatable implementieren, verlieren die Möglichkeit, Datensätze mit meinen SQLMetal generierten Klassen zu aktualisieren. Wenn Änderungen Absenden erhalte ich die folgende Ausnahme:Falsche Syntax in der Nähe des Schlüsselwortes "WHERE" beim Aktualisieren von Tabelle mit SQLMetal generierte Klasse

falsche Syntax nahe dem Schlüsselwort ‚WHERE‘

Der folgende Beispielcode das Problem veranschaulicht. Es läuft gut, bis die Umsetzung IEquatable:

var connection = "Your connection string"; 
var dbInsert = new DBTest(connection); 
var recordToInsert = new TestTable() 
{ 
    PrimaryKey1 = 123, 
    PrimaryKey2 = "Red", 
    TheValue = Guid.NewGuid().ToString(), 
}; 
dbInsert.TestTable.InsertOnSubmit(recordToInsert); 
dbInsert.SubmitChanges(); 

var dbEdit = new DBTest(connection); 
dbEdit.Log = Console.Out; 
var ti1 = dbEdit.TestTable.Single(x => x.PrimaryKey1 == 123 && x.PrimaryKey2 == "Red"); 
ti1.TheValue = Guid.NewGuid().ToString(); 
dbEdit.SubmitChanges(); 

Das ist meine Implementierung für IEquatable (automatisch von ReSharper) ist:

public partial class TestTable : IEquatable<TestTable> 
{ 
    public bool Equals(TestTable other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return _PrimaryKey1 == other._PrimaryKey1 && string.Equals(_PrimaryKey2, other._PrimaryKey2) && string.Equals(_TheValue, other._TheValue); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != this.GetType()) return false; 
     return Equals((TestTable)obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      var hashCode = _PrimaryKey1; 
      hashCode = (hashCode * 397)^(_PrimaryKey2 != null ? _PrimaryKey2.GetHashCode() : 0); 
      hashCode = (hashCode * 397)^(_TheValue != null ? _TheValue.GetHashCode() : 0); 
      return hashCode; 
     } 
    } 
} 

bei der Abfrage Werfen Sie einen Blick, die im Ausgabefenster druckt. Wenn IEquatable implementiert ist, ist die SET-Klausel leer (und bewirkt, dass die Ausnahme ausgelöst werden.):

UPDATE [dbo] [Testtable]
SET
WHERE ([PrimaryKey1] = @ p0) und ([PrimaryKey2] = @ p1) UND ([TheValue] = @ p2)
- @ p0: Eingang Int (Größe = -1; Prec = 0; Skalierung = 0) [123]
- @ p1: Eingang NVarChar (Größe = 4000; Prec = 0; Skala = 0) [Rot]
- @ p2: Eingabe NVarChar (Größe = 4000; Prec = 0; Skala = 0) [8dedfdca-84e9-4b7a-9268-4bbdde2e9ad2]

012 Hier

ist die gleiche Leistung ohne IEquatable umgesetzt.

UPDATE [dbo] [Testtable]
SET [theValue] = @ p3
WHERE ([PrimaryKey1] = @ p0) und ([PrimaryKey2 ] = @ p1) UND ([TheValue] = @ p2)
- @ p0: Eingabe Int (Größe = -1; Prec = 0; Skala = 0) [123]
- @ p1: Eingang NVarChar (Größe = 4000; Prec = 0; Skala = 0) [Rot]
- @ p2: Eingang NVarChar (Size = 4000; Prec = 0; scale = 0) [8f6e72ee-f89e-40f3-830f-18e8b4b40f9e]
- @ p3: Input NVarChar (Size = 4000; Prec = 0; scale = 0) [1ecaff9d-d460-4f3e-B35D-138ddeb2fb63]

Wird dieses Verhalten erwartet? Gibt es einen Weg, um es zu umgehen?

Antwort

0

Es stellt sich heraus, dass das Überschreiben der GetHashCode() -Methode mit der Fähigkeit von DataContext, Änderungen zu verfolgen, verwechselt wird. Durch das Entfernen der GetHashCode-Überschreibung wurde das Problem behoben.