如何使用TableAdapter更新DataSet的单个表,而不对表名进行硬编码?

时间:2009-11-13 05:48:50

标签: vb.net reflection ado.net

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

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

我要做的是通过将表的名称与DataSet一起发送回Web服务,然后使用动态名称引用TableAdapter,为更新的DataTable实例化相应的TableAdapter。实例化TableAdapter的常规方法是:

Dim ta As New dsLookupsTableAdapters.tlkpMyTableTableAdapter

我想做的是这个,但当然不起作用:

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

有没有办法实现这一目标,还是我采取了错误的做法?我的另一种选择是为每个表编写单独的代码,我宁愿避免使用它!

4 个答案:

答案 0 :(得分:2)

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

object adapter = Activator.CreateInstance(Type.GetType("My.Namespace.MyDataSetTableAdapters." + myTable.Name + "TableAdapter"));

然后,因为TableAdapter没有通用接口,所以应该使用反射来调用其Update方法:

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

http://msdn.microsoft.com/en-us/library/system.type.getmethod.aspx

这是来自记忆,但大致足够接近。您还可以使用GetProperty获取连接属性并根据需要进行设置。

答案 1 :(得分:1)

在给定(字符串)类型名称的情况下,在运行时创建类型非常容易。

这是一个自包含的VB类,它说明了一种方法:使用System.Activator.CreateInstance使用类型名称的字符串表示创建类型实例。然后,您可以将其转换为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

答案 2 :(得分:1)

不确定我100%理解,你的DataSet中有一个DataTable,还是每个查找表有一个DataTable?

无论如何,也许您可​​以this approach按查找表进行过滤?

答案 3 :(得分:1)

如果您使用的是VB.Net 2008,请使用tableadaptermanager(http://msdn.microsoft.com/en-us/library/bb384426.aspx)。我认为这可以更容易编码:)

瓦德