我正在VB.net上执行此操作
我有一个名为'dt'的数据表,其结构如下:
4列: 'OptionId' 'ChoiceId' '选择' “说明”
Datatable dt大约有800条记录。
我正在将其传递给函数:
Process(dt,"VehicleChoice;VehicleChoice", "Choice;Description", "Choice;Description", "ChoiceId;ChoiceId")
Public Sub Process(ByRef dt As DataTable, ByVal TableNames As String, ByVal ColumnNames As String, ByVal TableColumnNames As String, ByVal IdentityColumns As String)
Dim aTableNames As String() = TableNames.Split(";")
Dim aColumnNames As String() = ColumnNames.Split(";")
Dim aTableColumnNames As String() = TableColumnNames.Split(";")
Dim aIdentityColumns As String() = IdentityColumns.Split(";")
' remove readonly from columns
For Each Column As String In aTableColumnNames
dt.Columns(Column).ReadOnly = False
dt.Columns(Column).MaxLength = -1
Next
' ProcessFurther
For Each row As DataRow In dt.Rows
For i As Integer = 0 To aTableColumnNames.Length - 1
ProcessFurther(row(aTableColumnNames(i)), aTableNames(i), aColumnNames(i), (row(aIdentityColumns(i)))
Next
Next
End Sub
Public Function ProcessFurther(ByRef OriginalValue As Object, ByVal TableName As String, ByVal ColumnName As String, ByVal IdentityValue As Integer) As String
Dim OriginalValue = Some value which is not even related with any of these codes, but uses the params to retrieve this value.
Return OriginalValue
End Function
所以这里的功能很简单,我不知道为什么会收到这个错误:(来自Log4Net)
“ OptionId”列不允许为空。
System.Data
无效CheckNullable(System.Data.DataRow)
at System.Data.DataColumn.CheckNullable(DataRow row)
at System.Data.DataColumn.CheckColumnConstraint(DataRow row, DataRowAction action)
at System.Data.DataTable.RaiseRowChanging(DataRowChangeEventArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent)
at System.Data.DataTable.SetNewRecordWorker(DataRow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean suppressEnsurePropertyChanged, Int32 position, Boolean fireEvent, Exception& deferredException)
at System.Data.DataRow.EndEdit()
at System.Data.DataRow.set_Item(DataColumn column, Object value)
at ProcessFurther(DataTable& dt, String TableNames, String ColumnNames, String TableColumnNames, String IdentityColumns) in the For Loop (Stack trace has Line No of that For Loop, not the actual function.)
这里对我来说最大的困惑是,为什么/ OptionId在这里甚至是一个问题。在处理过程中甚至没有涉及,虽然它只是数据表的一部分。这对我完全没有任何意义。同样,这是随机发生的。可能会持续1-2分钟。它将消失约几个小时,并在一段时间后再次表现相同。它没有模式,出错或不出错时数据仍然相同。
如果有人对此有所帮助,请提供帮助,谢谢
答案 0 :(得分:1)
我想我知道问题出在哪里了,问题是您在不应该使用ByRef
的情况下感到惊讶。停止使用ByRef
并了解其实际功能,然后仅在有特殊要求时使用它。您的ProcessFurther
方法如下:
Public Function ProcessFurther(ByRef OriginalValue As Object,
ByVal TableName As String,
ByVal ColumnName As String,
ByVal IdentityValue As Integer) As String
这是您的称呼方式:
ProcessFurther(row(aTableColumnNames(i)),
aTableNames(i),
aColumnNames(i),
row(aIdentityColumns(i)))
通过声明参数ByRef
,您具体是说,应将方法内分配给该参数的所有内容分配回您最初传入的内容。首先传入的是row(aTableColumnNames(i))
,因此,当您在方法第一行中分配给参数时,您将分配给DataRow
的指定列。大概您要分配的是DBNull.Value
,这就是为什么您会收到一条错误消息,告诉您该列不接受NULL。
当我对您关于从参数中删除ByRef
的问题发表评论时,我实际上是在谈论dt
方法的Process
参数。那不是伤害你,但无论如何都不应该伤害你。在那个阶段,我还没有注意到您也在其他地方使用它。在这种情况下,它会伤害您。除非您特别需要,否则请勿使用ByRef
。如果您不知道何时需要,请学习。这不是VB6,您可以在其中使用它来停止复制大对象。在VB.NET中,作为类实例的任何对象都是引用类型,因此,无论如何通过值传递时都不会被复制。