Вычисляемые столбцы в SQL Server с дозвуковой - PullRequest
0 голосов
/ 12 декабря 2010

Мне не удалось вставить данные в таблицу с вычисляемым столбцом с помощью Subsonic.Это известная ошибка?И как я могу это решить?

Ответы [ 3 ]

1 голос
/ 12 апреля 2012

Я исправил это, может быть .... В SQLSErver.ttinclude вокруг строки 171 я изменил

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

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

Теперь я ненавижу это как решение, но у класса Column нет свойства для IsComputer. (или IsReadOnly) так что это по крайней мере остановило вставки от сбоя

Надеюсь, это поможет - опубликую снова, если я найду лучшее решение

Mike

1 голос
/ 14 декабря 2010

Это код, который SubSonic запускает для БД, чтобы определить, является ли он вычисляемым столбцом:

const string COLUMN_SQL=@"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 TABLE_NAME=@tableName
    ORDER BY OrdinalPosition ASC";

Это утверждение должно представлять интерес:

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

Сначала вы должны запустить это для своей базы данных, чтобы определить, верен ли результат.

Второе, что я заметил, это то, что, даже если это значение запрашивается из БД, оно не устанавливается в коде:

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;
}

Код от https://github.com/subsonic/SubSonic-3.0-Templates/blob/master/ActiveRecord/SQLServer.ttinclude

Вам следует изменить локальную копию SQLServer.ttinclude и добавить строку (перед методом result.Add (col)), которая выглядит следующим образом:

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

(в зависимости от результата запроса это может быть «ДА» вместо «1»). Объект Column имеет свойство IsComputed,

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

но опять же, я не знаю, соблюдается ли это при обновлении / вставке.
Если это не так, попробуйте установить для col.IsReadOnly значение true.

И последнее. Если модификация SQLServer.ttinclude устраняет вашу проблему, вы должны добавить запрос на получение на дозвуковой странице github.

Edit: Прежде чем возиться с SQLServer.ttinclude, вы можете добавить

col.IsComputed = true;

непосредственно к вашему файлу Structs.cs (но он будет переопределен при следующем запуске шаблона).

0 голосов
/ 04 октября 2011

Я все еще получаю эту ошибку при вставке (добавлении) строки в таблицу SQL с вычисляемым столбцом:

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.

Кто-нибудь добился прогресса в этом или это все еще ошибка? Использование Subsonic.Core версии 3.0.0.3.

Я следовал очень хорошему совету SchlaWiener, но, увы, как он / она мог подозревать, даже добавление IsComputed = true или даже IsReadOnly = true вручную в файл Structs.cs, похоже, по-прежнему генерирует вычисляемый столбец в инструкции INSERT и, таким образом, ошибка все еще существует.

Я не загружал и не проверял исходный код Subversion, чтобы увидеть, игнорируются ли столбцы IsComputed или IsReadOnly, но, основываясь на экспериментах, кажется, что они включены в оператор INSERT и, следовательно, являются источником досадного дефекта.

Кто-нибудь знает какие-нибудь обходные пути?

Спасибо.

PS для чего я стою, я отправил проблему 275 в github ... Если бы я был более уверен, я бы сделал исправление ... Я мог бы попробовать это дальше. КСТАТИ FWIW: комментирование свойства в ActiveRecord.cs делает проблему исчезает (временно, пока вы не перезапустите ваши шаблоны T-4) И пока вы читаете это свойство через сохраненный процесс. https://github.com/subsonic/SubSonic-3.0/issues/275

...