2014-01-30 3 views
-1

Я в затруднении на этом. У меня есть класс, который наследуется от «BaseClass». BaseClass имеет защищенный член, называемый «UpdateData».VB.net inheritance, Участник не найден только на одном звонке

У меня есть класс «DataAccess», который наследуется от «UpdateData». DataAccess имеет много разных вызовов, которые используют метод «UpdateData». Это отлично работает, за исключением одного метода на «DataAccess», который возвращает исключение «Member Not found».

Я очистил и перестроил, и это происходит в Visual Studio, а также при развертывании на сервере. Вызов «Добавить» работает, но вызов «Добавить деталь» не работает.

Я попытался удалить перечисленные ниже области транзакций, попробовал использовать шаблон фабрики, чтобы получить новый экземпляр для каждого вызова, но ни один из них не сработал. Я бы предпочел не открывать этот метод как «общедоступный», поскольку у нас есть сотни классов, которые используют защищенный метод «UpdateData» просто отлично?

Любая помощь или новые идеи приветствуются!

''''On the base class 
Protected Sub UpdateData(ByVal connString As String, ByVal procName As String, ByVal ParamArray params As Object()) 
    UpdateDataWithTimeout(connString, procName, getTimeoutSetting, params) 
End Sub 

''''On the inherited class. This one works 
Protected Friend Overridable Sub Add(ByVal s1 As String, _ 
         ByRef s2 As String, _ 
         ByVal s3 As String, _ 
         ByVal params As List(Of Object)) 

     Try 

      params.Insert(0, s1) 
      params.Insert(1, s2) 
      params.Insert(2, s3) 

      UpdateData(DB, SPI_PROC1, params.ToArray()) 

     Catch ex As Exception 
      Throw ex 
     End Try 
    End Sub 

''''On the inherited "DataAccess" class. This one fails. 
Protected Friend Overridable Sub AddDetail(ByVal ParamArray parms As Object()) 
    If Condition1 Then 
      UpdateData(_sysConn, SPI_PROC, parms) 
    End If 
    End Sub 

''''This is from a method in the class calling the "DataAccess" code 
Dim da As DataAccess 

da = New DataAccess(strVariable) 

Using scope As New TransactionScope(TransactionScopeOption.RequiresNew) 

    ''''This call works just fine and can find "UpdateData" 
    da.Add(string1, string2, string3, objectParameterList) 

    'Separate database, so avoid MSDTC with new transaction scope 
    Using scope2 As New TransactionScope(TransactionScopeOption.RequiresNew) 
     ''''This call fails to find UpdateData 
     da.AddDetail(string1, string5, string6, string7, string8, string3) 

     scope2.Complete() 
     scope.Complete() 
    End Using 

End Using 

Добавление: Существует разница в IL здесь с одним существом «позднего связывания» (что мне нужно остановиться), но я не знаю, как?

В противном случае метод ....

IL_001f: ldstr  "UpdateData" 
    IL_0024: ldc.i4.3 
    IL_0025: newarr  [mscorlib]System.Object 
    IL_002a: stloc.1 
    IL_002b: ldloc.1 
    IL_002c: ldc.i4.0 
    IL_002d: ldarg.0 
    IL_002e: ldfld  string DataAccess::_sysConn 
    IL_0033: stelem.ref 
    IL_0034: ldloc.1 
    IL_0035: ldc.i4.1 
    IL_0036: ldloc.0 
    IL_0037: call  object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) 
    IL_003c: stelem.ref 
    IL_003d: ldloc.1 
    IL_003e: ldc.i4.2 
    IL_003f: ldarg.1 
    IL_0040: stelem.ref 
    IL_0041: ldloc.1 
    IL_0042: stloc.2 
    IL_0043: ldloc.2 
    IL_0044: ldnull 
    IL_0045: ldnull 
    IL_0046: ldc.i4.3 
    IL_0047: newarr  [mscorlib]System.Boolean 
    IL_004c: stloc.3 
    IL_004d: ldloc.3 
    IL_004e: ldc.i4.0 
    IL_004f: ldc.i4.1 
    IL_0050: stelem.i1 
    IL_0051: ldloc.3 
    IL_0052: ldc.i4.1 
    IL_0053: ldc.i4.1 
    IL_0054: stelem.i1 
    IL_0055: ldloc.3 
    IL_0056: ldc.i4.2 
    IL_0057: ldc.i4.1 
    IL_0058: stelem.i1 
    IL_0059: ldloc.3 
    IL_005a: ldc.i4.1 
    IL_005b: call  object [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.NewLateBinding::LateCall(object, 
                                class [mscorlib]System.Type, 
                                string, 
                                object[], 
                                string[], 
                                class [mscorlib]System.Type[], 
                                bool[], 
                                bool) 
    IL_0060: pop 
    IL_0061: ldloc.3 
    IL_0062: ldc.i4.0 
    IL_0063: ldelem.i1 
    IL_0064: brfalse.s IL_0088 
    IL_0066: ldarg.0 
    IL_0067: ldloc.2 
    IL_0068: ldc.i4.0 
    IL_0069: ldelem.ref 
    IL_006a: call  object [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue(object) 

От метода работы, здесь IL.

IL_003b: ldarg.0 
    IL_003c: ldstr  "conn" 
    IL_0041: ldstr  "proc" 
    IL_0046: ldarg.0 
    IL_0047: callvirt instance string DataAccess::get_SYSCODE_SPAPPEND() 
    IL_004c: call  string [mscorlib]System.String::Concat(string, 
                   string) 
    IL_0051: ldarg.s params 
    IL_0053: callvirt instance !0[] class [mscorlib]System.Collections.Generic.List`1<object>::ToArray() 
    IL_0058: callvirt instance void [BaseClass]BaseClass::UpdateData(string, 
                                  string, 
                                  object[]) 

ответ

0

Конечно, в тот момент, когда вы задаете вопрос, ответ приходит к вам.

Я изменил свои строковые переменные для SPI_PROC и SPI_PROC1 как частные константы в классе, а не переменные ... установите _sysConn и DB в конструкторе классов, и он переключил все на раннее связывание.

Так что проблема решена. Надеюсь, это спасет кого-то еще несколько часов.

Смежные вопросы