Vb.net 如何使用TableAdapter更新数据集的单个表,而不硬编码表名?

Vb.net 如何使用TableAdapter更新数据集的单个表,而不硬编码表名?,vb.net,reflection,ado.net,Vb.net,Reflection,Ado.net,这似乎是我正在做的一件非常基本的事情,但我仍在努力让它发挥作用 我的情况是这样的:我有一个包含大量查找表的项目,所有这些查找表都表示在一个单一类型的数据集中,每个查找都包含TableAdapter。我为这些查找表设计了一个编辑器,它应该允许一次编辑其中一个。我的前端是用VB和WinForms编写的,后端是SOAP web服务;我可以成功地将对数据集的更改传递回web服务,但找不到使用TableAdapter更新已更改的单个表的方法 我要做的是为更新后的DataTable实例化适当的TableAd

这似乎是我正在做的一件非常基本的事情,但我仍在努力让它发挥作用

我的情况是这样的:我有一个包含大量查找表的项目,所有这些查找表都表示在一个单一类型的数据集中,每个查找都包含TableAdapter。我为这些查找表设计了一个编辑器,它应该允许一次编辑其中一个。我的前端是用VB和WinForms编写的,后端是SOAP web服务;我可以成功地将对数据集的更改传递回web服务,但找不到使用TableAdapter更新已更改的单个表的方法

我要做的是为更新后的DataTable实例化适当的TableAdapter,方法是将表名连同数据集一起发送回web服务,然后使用动态名称引用TableAdapter。实例化TableAdapter的常规方法如下:

Dim ta As New dsLookupsTableAdapters.tlkpMyTableTableAdapter
我想做的是这样,但当然不行:

strTableName = "tlkpMyTable"
Dim ta As New dsLookupsTableAdapters(strTableName & "TableAdapter")

有没有办法做到这一点,或者我采取了完全错误的方法?我的另一个选择是为每个表编写单独的代码,这是我宁愿避免的

给定(字符串)类型名,在运行时创建类型非常容易

下面是一个自包含的VB类,它演示了一种方法:使用类型名的字符串表示创建类型实例。然后,您可以将其强制转换为DataAdapter基类,并像使用任何其他DataAdapter一样使用它

Public Class dsLookupsTableAdapters

    Public Function CreateInstance(ByVal strName As String) As Object
        CreateInstance = Nothing

        For Each a As System.Reflection.Assembly In System.AppDomain.CurrentDomain.GetAssemblies()
            Try
                Dim strAssemblyName As String() = a.FullName.Split(New Char() {","c})
                Dim strNameTemp As String = strAssemblyName(0) & "." & strName
                Dim instance As Object = System.Activator.CreateInstance(a.FullName, strNameTemp)
                If instance IsNot Nothing Then
                    Dim handle As System.Runtime.Remoting.ObjectHandle
                    handle = CType(instance, System.Runtime.Remoting.ObjectHandle)
                    Dim o As Object = handle.Unwrap()
                    CreateInstance = o
                    Exit For
                End If
            Catch ex As System.Exception
                Continue For ' ignore exception, means type isn't there
            End Try
        Next
    End Function


    Public Class tlkpMyTableTableAdapter
        Inherits System.Data.Common.DataAdapter

    End Class


    Public Sub Test()
        ' define type name. note that, in this sample, tlkpMyTableTableAdapter is a nested
        ' class and dsLookupsTableAdapters is the containing class, hence the "+". If, however,
        ' dsLookupsTableAdapters is a namespace, replace the "+" with a "."
        Dim typeName As String = "dsLookupsTableAdapters+tlkpMyTableTableAdapter"
        Dim adapter As System.Data.Common.DataAdapter
        Dim o As Object = CreateInstance(typeName)
        adapter = CType(o, System.Data.Common.DataAdapter)

    End Sub

End Class

不确定我是否100%理解,您的数据集中有一个数据表,还是每个查找表有一个数据表


无论如何,也许您可以按查找表进行筛选?

如果您使用的是VB.Net 2008,请使用tableadaptermanager()。我认为这将更容易编码:)


Wade

您可以使用Activator从TableAdapter的字符串名称创建TableAdapter的实例,就像您希望的那样:

object adapter = Activator.CreateInstance(Type.GetType("My.Namespace.MyDataSetTableAdapters." + myTable.Name + "TableAdapter"));
然后,由于TableAdapters没有公共接口,您应该使用反射来调用其更新方法:

adapter.GetType().GetMethod("Update").Invoke(adapter, null);


这是从内存中提取的,但大致足够接近。您还可以使用GetProperty获取连接属性并根据需要进行设置。

否,我的数据集中有多个数据表(带有TableAdapters)。加载应用程序时,我使用此数据集同时将所有查找表加载到内存中。然而,当更新查找表时,我希望能够通过只发送对给定表的修改和使用更新表的适当TabeAdvter来实现这一点。很抱歉,没有尽快回复您——我们现在正处于移动房屋的中间,而我还没有机会尝试它。我会尽快的,没问题。仅供参考,您的赏金将在半小时后到期,因此如果您想测试此代码,您可能希望尽快完成…:-)嗨,贾斯汀,我只是想让你知道我没有忘记你-我已经试过了代码,但还没能让它工作(我想主要是因为我自己的无知)。我不得不关注项目的另一部分,但本周我将尝试再次尝试。很抱歉,虽然我使用的是VS2008,但我编写的服务器只有.NET Framework v2.0,而TableAdapterManager仅在v3.5及更高版本中可用。不过,这将是一个有用的工具!由于它是VB.NET,请避免反射并使用CallByName(适配器,“Update”,CallType.Method,Nothing)谢谢大家,这就成功了。很抱歉,我花了这么长时间才回到这个话题上——我一直忙于这个项目的其他方面,这些方面更为紧迫。不幸的是,我似乎不能接受这个答案——有什么想法吗?嗯,刚刚发现你在赏金到期后不能接受答案,这有点烦人。伊利亚,你的回答是我本来会接受的,但它是在赏金过期之后才来的——无论如何,谢谢!