asp.net - Option Strict 设置为 ON 后期绑定问题
问题描述
' 1St step
Dim irregularWeldSpots = From row In spotsTable.AsEnumerable()
Where (CStr(row("FUNCJOINTCODE")) = currentJointKey
And ((Convert.ToDecimal(row("RESULTUNIT")) / Convert.ToDecimal(row("LENSDIAMUNIT"))) >= defectiveSpotIfSizeLessThanPercent
And (Convert.ToDecimal(row("RESULTUNIT")) / Convert.ToDecimal(row("LENSDIAMUNIT"))) < insufficientSpotIfSizeLessThanPercent)
Or (Convert.ToDecimal(row("RESULTUNIT")) / Convert.ToDecimal(row("LENSDIAMUNIT")) < defectiveSpotIfSizeLessThanPercent))
Select Case row
, IsInsufficient = ((Convert.ToDecimal(row("RESULTUNIT")) / Convert.ToDecimal(row("LENSDIAMUNIT"))) >= defectiveSpotIfSizeLessThanPercent
And (Convert.ToDecimal(row("RESULTUNIT")) / Convert.ToDecimal(row("LENSDIAMUNIT"))) < insufficientSpotIfSizeLessThanPercent)
, IsDefect = (Convert.ToDecimal(row("RESULTUNIT")) / Convert.ToDecimal(row("LENSDIAMUNIT"))) < defectiveSpotIfSizeLessThanPercent
' 2nd step
EvaluateDistanceBetweenIrregularSpots(resultTable,definitionsTable,currentJointKey,allWeldSpots,allWeldSpotsCount,defectiveWeldSpotsCount,
insufficientWeldspotsCount,irregularWeldSpots)
' 3rd step
Private Sub EvaluateDistanceBetweenIrregularSpots(ByRef resultTable As DataTable, ByRef definitionsTable As DataTable, As String, allWeldSpots As IEnumerable, allWeldSpotsCount As Integer, As Integer, insufficientWeldspotsCount As Integer,
As IEnumerable)
If Not ((insufficientWeldspotsCount + defectiveWeldSpotsCount) > 1) Then Return
For Each spot1 In irregularWeldSpots
If spot1.row("XUNIT") Is Nothing Then Continue For
For Each spot2 In irregularWeldSpots
If spot1.row("SPOTDESC") = spot2.row("SPOTDESC") Then Continue For
Dim x0 As Double = spot1.row("XUNIT")
Dim x As Double = spot2.row("XUNIT")
Dim y0 As Double = spot1.row("YUNIT")
Dim y As Double = spot2.row("YUNIT")
Dim z0 As Double = spot1.row("ZUNIT")
Dim z As Double = spot2.row("ZUNIT")
Dim distance As Double = Math.Sqrt((x - x0) ^ 2 + (y - y0) ^ 2 + (z - z0) ^ 2)
If distance >= spot1.row("LENSDIAMUNIT") Then Continue For
Dim message As String = String.Empty
If spot1.IsDefect And spot2.IsDefect Then
message = "One defect spot was found inside the sphere around another defect spot"
ElseIf (spot1.IsDefect And spot2.IsInsufficient) Or (spot1.IsInsufficient And spot2.IsDefect) Then
message = "One insufficient spot was found inside the sphere around a defect spot"
End If
If message.Length > 0 Then
Dim newRow As DataRow = resultTable.NewRow()
newRow("JointNo") = jointNumber
newRow("StatusMessage") = message
newRow("SpotCount") = allWeldSpotsCount
newRow("Insufficient") = insufficientWeldspotsCount
newRow("Defective") = defectiveWeldSpotsCount
newRow("SphereRadius") = "-"
resultTable.Rows.Add(newRow)
End If
Next
Next
End Sub
在“spot1.row(..) & spot2.row(..)”上选项 strict 设置为 ON 后后期绑定的第 3 步问题
解决方案
您应该能够从您之前的代码中弄清楚该做什么。在第 1 步中,您似乎已经认识到索引row
返回可能是Object
引用的事实,因此,如果您想使用一个值作为其实际类型,那么您需要转换/转换为该类型。在步骤 1 的代码中,您有:
CStr(row("FUNCJOINTCODE"))
和:
(Convert.ToDecimal(row("RESULTUNIT"))
您想将值用作类型String
或类型的地方Decimal
,那么为什么在您想将值用作类型的第 3 步中它应该有所不同Double
,例如
Dim x0 As Double = CDbl(spot1.row("XUNIT"))
虽然这没什么大不了的,但你真的应该只Convert
在实际需要转换数据类型时使用。例如,如果row("RESULTUNIT")
实际上包含 aString
并且您需要将其转换为 a Decimal
thenConvert.ToDecimal
是合适的,但如果数据已经是 aDecimal
那么您只执行转换,因为不需要转换。在这种情况下,您应该使用CDec
.
此外,您不应该一遍又一遍地使用相同的复杂表达式。在第 1 步中,您使用(Convert.ToDecimal(row("RESULTUNIT"))
了很多次,这很糟糕。我会像这样编写第 1 步代码:
Dim irregularWeldSpots = From row In spotsTable.AsEnumerable()
Let resultUnit = CDec(row("RESULTUNIT")),
lensDiamUnit = CDec(row("LENSDIAMUNIT"))
Where (CStr(row("FUNCJOINTCODE")) = currentJointKey AndAlso
resultUnit / lensDiamUnit >= defectiveSpotIfSizeLessThanPercent AndAlso
resultUnit / lensDiamUnit < insufficientSpotIfSizeLessThanPercent) OrElse
resultUnit / lensDiamUnit < defectiveSpotIfSizeLessThanPercent
Select row,
IsInsufficient = resultUnit / lensDiamUnit >= defectiveSpotIfSizeLessThanPercent AndAlso
resultUnit / lensDiamUnit < insufficientSpotIfSizeLessThanPercent,
IsDefect = resultUnit / lensDiamUnit < defectiveSpotIfSizeLessThanPercent
请注意,现在使用更好的缩进更容易阅读,使用Let
子句创建查询局部变量,并且它还使用更正确的AndAlso
而OrElse
不是“与and
或”。我还删除了多余的括号,但您可能更愿意保留它们。
关于括号的主题,我想知道您在该Where
条款中是否正确。请注意,And
andAndAlso
运算符始终优先于Or
andOrElse
运算符进行评估,因此,无论有没有多余的括号,您都在匹配前三个条件匹配或最后一个条件匹配的记录。也许这就是您想要的,但我怀疑您真正想要的是匹配第一个条件以及第二个和第三个或第四个条件。如果是这样,那么:
Where (CStr(row("FUNCJOINTCODE")) = currentJointKey AndAlso
resultUnit / lensDiamUnit >= defectiveSpotIfSizeLessThanPercent AndAlso
resultUnit / lensDiamUnit < insufficientSpotIfSizeLessThanPercent) OrElse
resultUnit / lensDiamUnit < defectiveSpotIfSizeLessThanPercent
会是这样的:
Where CStr(row("FUNCJOINTCODE")) = currentJointKey AndAlso
((resultUnit / lensDiamUnit >= defectiveSpotIfSizeLessThanPercent AndAlso
resultUnit / lensDiamUnit < insufficientSpotIfSizeLessThanPercent) OrElse
resultUnit / lensDiamUnit < defectiveSpotIfSizeLessThanPercent)
编辑:
现在问题更清楚了,因为我意识到该代码来自不止一种方法。您应该定义自己的类型,而不是使用匿名类型:
Public Class SpotRow
Public Property Row As DataRow
Public Property IsInsufficient As Boolean
Public Property IsDefect As Boolean
End Class
然后,您可以更改 LINQ 查询以创建该类型的实例而不是匿名类型:
Select New SpotRow With {.Row = row,
.IsInsufficient = resultUnit / lensDiamUnit >= defectiveSpotIfSizeLessThanPercent AndAlso
resultUnit / lensDiamUnit < insufficientSpotIfSizeLessThanPercent,
.IsDefect = resultUnit / lensDiamUnit < defectiveSpotIfSizeLessThanPercent}
然后,您可以将生成的列表作为 anIEnumerable(Of SpotRow)
而不是IEnumerable
. 我不会尝试提供方法声明,因为您发布的代码是无意义的,因为它具有没有参数名称的参数类型。只需更改相关参数的类型即可。您会发现您现在可以访问Row
每个项目的属性。
推荐阅读
- c - 打印 c 中类型的最大数字 - 努力格式化正确的类型
- asp.net - System.Diagnostics.TraceSource 未将数据发送到 Application Insights
- reactjs - 如何在 SPA 中动态加载具有反应的时刻语言环境并强制在本地环境和生产环境中重新渲染?
- php - PHP通过循环上传多个图像
- flask - Flask 2.0 async - RuntimeError:在请求上下文之外工作
- wordpress - 当我尝试从 REST API 获取 token_id 时,邮递员出现 401 错误
- python-3.x - 试图查找过去一小时内创建的任何 AMI
- html - 同时从父级和子级更改 flex 会触发闪烁
- python - 为什么 Gtk.TextView 中的空行与行号不对齐但带有文本的行不对齐?
- sql-server - 存储过程返回的结果在调用之间交叉