2010-12-12 110 views
0

我無法使用Subsonic將數據插入帶有計算列的表中。這是衆所周知的錯誤嗎?我該如何解決它?使用Subsonic在SQL Server中計算列

+0

向表中插入數據時,確保** not **爲計算列提供值。在普通的SQL中,只要確保沒有在INSERT(...)語句中列出的那一列。不知道你怎麼可以在SubSonic中做到這一點,雖然....(btw:v2或v3 ??相當不同的野獸......) – 2010-12-12 21:25:11

+0

SubSonic v3。它生成包括計算列的SQL INSERT命令。我不知道如何強制SubSonic生成INSERT命令沒有這個列。 – Anton 2010-12-13 12:12:19

回答

1

這是亞音速違背了數據庫,以確定它是否是一個計算列代碼:

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 

首先,你應該運行,對你的數據庫以確定結果是否爲真。

我注意到的第二件事是,即使該值從數據庫中查詢,它不是在代碼中設置:

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

(根據結果從查詢它命名爲c應該是「是」而不是「1」)。 列對象有一個IsComputed財產,

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

但同樣,如果更新/插入過程中尊重我不知道。
如果不是,請嘗試將col.IsReadOnly設置爲true。

最後一件事。 如果SQLServer.ttinclude修改修復了您的問題,則應該向亞音速github頁面添加拉取請求。

編輯: 之前與SQLServer.ttinclude亂搞,你可以直接添加

col.IsComputed = true; 

線到您Structs.cs文件(但將在下一次執行模板覆蓋)。

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中發出計算列聲明,因此該錯誤仍然存​​在。

我沒有下載並檢查Subversion源代碼以查看IsComputed或IsReadOnly列是否被忽略,但基於實驗,它們似乎被包含在INSERT語句中,因此是惱人缺陷的來源。

有誰知道任何解決方法嗎?

謝謝。

PS爲什麼值得我在github上提交了一個問題275如果我更有信心我會做出修復......我可能會嘗試下一步。 BTW FWIW:在ActiveRecord.cs中註釋掉該屬性會導致問題消失(暫時,直到您重新運行T-4模板)並且只要您通過存儲過程讀取該屬性即可。 https://github.com/subsonic/SubSonic-3.0/issues/275

1

我有固定這也許.... 在SQLSErver.ttinclude四圍線171我改變

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

到 col.AutoIncrement = RDR [ 「IsIdentity」]。的ToString()= =「1」|| RDR [ 「IsComputed」]的ToString()== 「1」。

現在,我討厭這是一個解決方案,但列類不具有IsComputer (或IsReadOnly)屬性 所以這至少停止了刀片從失敗

希望幫助 - 會如果我再次發佈找到更好的解決方案

Mike