2010-12-12 12 views
0

サブソニックを使用して計算列のデータをテーブルに挿入できませんでした。それはよく知られているバグですか?そして私はそれをどのように解決することができますか?サブソニックを使用したSQL Serverの計算列

+0

テーブルにデータを挿入するときは、計算された列に値を指定しないでください。単純なSQLでは、その列がINSERT(...)文にリストされていないことを確認してください。あなたはSubSonicでこれをどうやってやっていいのか分かりません....(btw:v2かv3?まったく違う獣....) –

+0

SubSonic v3。計算カラムを含むSQL INSERTコマンドを生成します。私はSubSonicがこの列なしでINSERTコマンドを生成する方法を知らない。 – Anton

答えて

1

これは、計算列かどうかを決定するために、DBに対するコード亜音速の実行です:

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

この文は、関心のあるべき:

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

まず、あなたのDBに対してということを実行する必要があります結果が真であるかどうかを判断する。

私は気づいた二つ目は、この値はDBから照会された場合でも、それはコードで設定されていない、ということです:コードはhttps://github.com/subsonic/SubSonic-3.0-Templates/blob/master/ActiveRecord/SQLServer.ttinclude

からである

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

あなたを変更する必要があります

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

は(はCクエリからの結果に応じて、このようになりますSQLServer.ttincludeのローカルコピーと(result.Add(COL)メソッドの前)の行を追加します。 "1"の代わりに "YES"にしてください)。 Columnオブジェクトは、

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

IsComputed性質を持っていますが、それは更新/挿入時に尊敬されている場合には、再度、私は知りません。
そうでない場合は、col.IsReadOnlyをtrueに設定してください。

最後の1つです。 SQLServer.ttincludeの変更によって問題が解決された場合は、サブソニックgithubページにプルリクエストを追加する必要があります。

編集: SQLServer.ttincludeをいじり前に、あなたのStructs.csをファイル(それはあなたがテンプレートを実行次回上書きされますあなたに直接

col.IsComputed = true; 

行を追加することができます)。

0

計算列で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ステートメントが存在し、したがってバグはまだ存在します。

IsComputedまたはIsReadOnly列が無視されているかどうかを確認するためにSubversionのソースコードを確認しませんでしたが、実験に基づいてINSERTステートメントに含まれているように見えます。

誰かが回避策を知っていますか?

ありがとうございました。

私は問題を275で提出しました。私がもっと自信を持っていたら、私は修正をしました。 BTW FWIW:ActiveRecord.csのプロパティをコメントアウトすると、T-4テンプレートを再実行するまで一時的に問題が解決され、ストアドプロシージャを介してそのプロパティを読み取る限り、問題は解決します。

https://github.com/subsonic/SubSonic-3.0/issues/275
1

私は多分これを修正した.... は、ライン171約SQLSErver.ttincludeラウンドでは、私は[ "IsIdentity"]

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

にcol.AutoIncrement = RDRを変え。ToStringメソッド()= = "1" || rdr ["IsComputed"]。ToString()== "1";

今ので、これは、少なくとも助け

希望を失敗からの挿入を停止し 私は解決策としてこれを嫌うが、列クラスはIsComputer (またはIsReadOnlyの)のためのプロパティを持っていない - I場合は、再度掲載します

マイク

関連する問題