是否可以为SqlParameter实现扩展运算符?

时间:2013-08-29 15:00:17

标签: c# .net vb.net visual-studio

参加以下课程:

Public Class DocumentNumber
    Private m_DOC_NUMBER As Integer = 0

    Public Sub New(ByVal DOC_NUMBER As Integer)
        m_DOC_NUMBER = DOC_NUMBER
    End Sub

    Public Sub New(ByVal DEPOT_CODE As String)
        Dim ParseInput As Integer = 0
        If Integer.TryParse(DEPOT_CODE, ParseInput) = False Then
            m_DOC_NUMBER = 0
        Else
            m_DOC_NUMBER = ParseInput
        End If
    End Sub

    ''' <summary>
    ''' Returns the DOC_NUMBER as a zero-padded number, eg: 0000028374
    ''' </summary>
    Public Overrides Function ToString() As String
        Return Right("0000000000" & m_DOC_NUMBER.ToString(), 10)
    End Function

    ''' <summary>
    ''' Returns the DOC_NUMBER as an integer, use .ToString() zero-padded version.
    ''' </summary>
    Public Function ToInteger() As Integer
        Return m_DOC_NUMBER
    End Function

    ''' <summary>
    ''' Ensure that the DOC_NUMBER object has an implicit convert if assigned to an integer / string
    ''' </summary>
    Public Shared Widening Operator CType(ByVal d As DocumentNumber) As Integer
        Return d.ToInteger()
    End Operator

    Public Shared Widening Operator CType(ByVal d As DocumentNumber) As String
        Return d.ToString()
    End Operator

End Class

这个类允许我从字符串或整数声明一个DocID:

Dim DocumentID As New DOC_NUMBER("00123")
Dim DocumentID As New DOC_NUMBER(123)

这些可以通过调用ToInteger()&amp; ToString()

Dim NewDocumentID as Integer = DocumentID.ToInteger()
Dim NewDocumentID as String = DocumentID.ToString()

注意两个Widening Operator - 这些也允许隐式转换,意味着.ToInteger().ToString()在将此类的实例分配给整数或字符串时可以省略,例如:

Dim NewDocumentID as Integer = DocumentID
Dim NewDocumentID as String = DocumentID

到目前为止;这一切都很有效,我的下一个挑战是在分配给SqlParameter()对象时添加隐式转换。

如您所知,如果您将对象分配给新的SqlParameter(),则可以省略数据类型,SqlParameter()对象将自动识别出来 - 但是,如果我尝试使用我的对象它显然失败了:

m_db_QueryParams.Add(New SqlParameter("@DOC_NUMBER", OrderNumber))

这会产生以下错误(这是可以理解的!):

从对象类型DocumentNumber到已知的托管提供程序本机类型不存在映射。

我的问题:在分配给没有提供数据类型的Widening Operator时,是否可以向我的班级添加.ToString()并返回SqlParameter()方法像这样):

m_db_QueryParams.Add(New SqlParameter("@DOC_NUMBER", OrderNumber)) 'Convert as a string for the SqlParameter

我已将此问题标记为VB&amp; c#作为任何一种语言的解决方案都是合适的。

1 个答案:

答案 0 :(得分:1)

这里的问题是SqlParameter构造函数采用类型Object的参数。

由于所有类都继承自Object,因此在添加值时不会调用扩展运算符。

这是因为您的DocumentNumber类型的值已经属于Object类型,因此无需转换为String

我认为最好的办法是创建一些代码模式。您可以在SqlParameterCollection上创建一个扩展方法,如:

Module SqlParameterExtensions

  <Extension()>
  Public Sub MyAddWithValue(coll As SqlParameterCollection, paramName As String, paramValue As Object)
    If (TypeOf paramValue Is DocumentNumber) Then
        coll.AddWithValue(paramName, paramValue.ToString())
    Else
        coll.AddWithValue(paramName, paramValue)
    End If
  End Sub
End Module

并称之为

Module Module1

    Sub Main()
        Dim com As New SqlCommand
        Dim docNo As New DocumentNumber
        com.Parameters.MyAddWithValue("@DOC_NO", docNo)
    End Sub

End Module

或者你可以为SqlParameters创建一个“工厂”方法;

Public Shared Function CreateParameter(name As String, value As Object) As SqlParameter
    If (TypeOf value Is DocumentNumber) Then
        value = value.ToString()
    End If

    Return New SqlParameter(name, value)
End Function