2010-12-12 85 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