2010-12-12 12 views
0

Ich konnte keine Daten in Tabelle mit berechneter Spalte unter Verwendung von Subsonic einfügen. Ist es ein bekannter Fehler? Und wie kann ich es lösen?Berechnete Spalten in SQL Server mit Subsonic

+0

Wenn Sie Daten in eine Tabelle einfügen, stellen Sie sicher ** ** **, um einen Wert für die berechnete Spalte anzugeben. Stellen Sie in reinem SQL sicher, dass Sie diese Spalte nicht in Ihrer INSERT-Anweisung (...) aufgelistet haben. Nicht sicher, wie Sie das in SubSonic tun könnten, obwohl .... (übrigens: v2 oder v3 ?? Ganz andere Bestien ....) –

+0

SubSonic v3. Es generiert den SQL INSERT-Befehl einschließlich der berechneten Spalte. Ich weiß nicht, wie man SubSonic generate INSERT-Befehl ohne diese Spalte erzwingt. – Anton

Antwort

1

Dies ist der Code SubSonic der db läuft gegen zu bestimmen, ob es sich um eine berechnete Spalte ist:

const string [email protected]"SELECT 
     TABLE_CATALOG AS [Database], 
     TABLE_SCHEMA AS Owner, 
     TABLE_NAME AS TableName, 
     COLUMN_NAME AS ColumnName, 
     ORDINAL_POSITION AS OrdinalPosition, 
     COLUMN_DEFAULT AS DefaultSetting, 
     IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, 
     CHARACTER_MAXIMUM_LENGTH AS MaxLength, 
     DATETIME_PRECISION AS DatePrecision, 
     COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity, 
     COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE [email protected] 
    ORDER BY OrdinalPosition ASC"; 

Diese Aussage von Interesse sein sollte:

COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), 
     COLUMN_NAME, 'IsComputed') as IsComputed 

Zuerst sollten Sie, dass gegen Ihre db laufen um festzustellen, ob das Ergebnis wahr ist.

Das zweite, was mir aufgefallen ist, dass, selbst wenn dieser Wert aus der db abgefragt wird, ist es nicht im Code festgelegt ist:

List<Column> LoadColumns(Table tbl){ 
    var result=new List<Column>(); 
    var cmd=GetCommand(COLUMN_SQL); 
    cmd.Parameters.AddWithValue("@tableName",tbl.Name); 

    using(IDataReader rdr=cmd.ExecuteReader(CommandBehavior.CloseConnection)){ 
     while(rdr.Read()){ 
      Column col=new Column(); 
      col.Name=rdr["ColumnName"].ToString(); 
      col.CleanName=CleanUp(col.Name); 
      col.DataType=rdr["DataType"].ToString(); 
      col.SysType=GetSysType(col.DataType); 
      col.DbType=GetDbType(col.DataType); 
      col.AutoIncrement=rdr["IsIdentity"].ToString()=="1"; 
      col.IsNullable=rdr["IsNullable"].ToString()=="YES"; 
      int.TryParse(rdr["MaxLength"].ToString(),out col.MaxLength); 

      result.Add(col); 
     } 

    } 

    return result; 
} 

Der Code ist von https://github.com/subsonic/SubSonic-3.0-Templates/blob/master/ActiveRecord/SQLServer.ttinclude

sollten Sie ändern Ihre lokale Kopie der SQLServer.ttinclude und fügen sie eine Zeile (vor dem result.Add (col) -Methode), die wie folgt aussieht:

col.IsComputed=rdr["IsComputed"].ToString()=="1"; 

(aus der Abfrage auf das Ergebnis je es c sollte "JA" statt "1" sein. Das Column-Objekt verfügt über eine IsComputed Eigenschaft,

https://github.com/subsonic/SubSonic-3.0/blob/master/SubSonic.Core/Schema/IColumn.cs

aber wieder, ich weiß nicht, ob es beim Update/Insert eingehalten wird.
Wenn dies nicht der Fall ist, versuchen Sie col.IsReadOnly auf True zu setzen.

Eine letzte Sache. Wenn die Änderung SQLServer.ttinclude Ihr Problem behebt, sollten Sie eine Pull-Anforderung zur Seite subsonic github hinzufügen.

Edit: Bevor mit dem SQLServer.ttinclude Herumspielen können Sie die

hinzufügen
col.IsComputed = true; 

Linie direkt an Sie Ihr Structs.cs Datei (aber es wird das nächste Mal, wenn Sie die Vorlage ausführen außer Kraft gesetzt werden).

0

ich immer noch diese Fehlermeldung erhalten, wenn sie mit einer berechneten Spalte eine Zeile in eine SQL-Tabelle einfügen (Hinzufügen):

System.Data.SqlClient.SqlException: The column "{0}" cannot be modified because it is either a computed column or is the result of a UNION operator. 

hat jemand irgendwelche Fortschritte auf diesem oder ist dies immer noch ein Fehler? Verwenden von Subsonic.Core Version 3.0.0.3.

Ich folgte SchlaWieners sehr guten Ratschlag, aber leider, wie er/sie vielleicht vermutet hatte, scheint selbst das Hinzufügen von IsComputed = true oder sogar IsReadOnly = true manuell zur Datei Structs.cs immer noch die berechnete Spalte im INSERT zu emittieren Aussage und somit der Fehler noch existiert.

Ich habe den Subversion-Quellcode nicht heruntergeladen und überprüft, um zu sehen, ob IsComputed- oder IsReadOnly-Spalten ignoriert werden, aber aufgrund von Experimenten scheinen sie in der INSERT-Anweisung enthalten zu sein und sind somit die Quelle eines störenden Fehlers.

Kennt jemand Workarounds?

Danke.

PS für das, was es wert ist Ich habe eine Ausgabe 275 in Github eingereicht ... Wenn ich selbstsicherer wäre, würde ich den Fehler beheben ... Ich könnte das als nächstes versuchen. BTW FWIW: Auskommentieren der Eigenschaft in der ActiveRecord.cs macht das Problem weg (vorübergehend, bis Sie Ihre T-4-Vorlagen erneut ausführen) UND solange Sie diese Eigenschaft über eine gespeicherte Prozedur lesen. https://github.com/subsonic/SubSonic-3.0/issues/275

1

Ich reparierte haben dies vielleicht .... In SQLSErver.ttinclude rund um die Linie 171 I

geändert
 col.AutoIncrement=rdr["IsIdentity"].ToString()=="1"; 

zu col.AutoIncrement = rdr [ "IsIdentity"]. ToString() = = "1" || rdr ["IsComputed"]. ToString() == "1";

Jetzt hasse ich dies als eine Lösung, aber die Spalte Klasse nicht über eine Eigenschaft für IsComputer (oder IsReadOnly) so dass diese zumindest gestoppt, die Einsätze von Versagen

Hoffnung, das hilft - wieder abgeben I Finden Sie eine bessere Lösung

Mike

Verwandte Themen