Click here to Skip to main content
15,880,905 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi.

Creating a .NET DataSet is easy with Visual Studio, but there is no way to expose that object from a shared DLL. Indeed, when we use only one EXE, we have the same problem: dynamically changing the Dataset ConnectionString which is only a parameter does not seem natural: we traffic a value inked in the assembly!? In addition, the same dataset can be used to manipulate different databases at the same time, which is in contradiction with the existence of a single variable usage (a connectionstring of the project resource).

So I wanted your opinion on the issue, although from my side I found an idea that does not satisfy me because I find it wobbly.

What I have tried:

My current solution : search and replace every " friend" by " public" in dataset designer file, to be able to use a reflexion code based on TableName value, to predict TableAdapter object Name, to dynamically create a new TableAdapter instance from real one, and pass a connexion as parameter already managed before this.

VB
#Region "Dataset"
    Public Function TableAdapterRoot(_Name As String) As String

        'exemple : Dim x As ECI_Data.ESTX_DataSet_2TableAdapters.ARTICLETableAdapter

        'racine ECI_Data.
        Dim szRootObject As String = "ECI_Data." & _type.ToString & "_DataSet"
        '+ version
        szRootObject &= "_" & _Version.Major & "TableAdapters."
        '+ Nom classe 
        szRootObject &= _Name & "TableAdapter"
        Return szRootObject
    End Function

    Public Function ChargerTable(_TableName As String, Optional ByVal Reload As Boolean = False, Optional ByVal clone As Boolean = False) As DataTable

        Dim _ClassName As String
        Dim _Adapter As Object

        Try
            'si "rechargement forcé" pas actif et déjà pourvu alors on ne fait rien sinon que de renvoyer ce que l'on a
            If Not Reload And DataSet.Tables(_TableName).Rows.Count > 0 Then
                ChargerTable = DataSet.Tables(_TableName)
                Exit Function
            End If

            _ClassName = TableAdapterRoot(_TableName)
            '_Adapter = System.Activator.CreateInstance("ECI_Data", _ClassName).Unwrap()
            _Adapter = System.Reflection.Assembly.GetExecutingAssembly.CreateInstance(_ClassName)
            _Adapter.Connection = _Connexion
            _Adapter.Transaction = _Transaction
            Dim dt As DataTable = Nothing
            If clone Then
                dt = DataSet.Tables(_TableName).Clone
            Else
                dt = DataSet.Tables(_TableName)
            End If
            _Adapter.Fill(dt)
            ChargerTable = dt 'DataSet.Tables(_TableName)
            _Adapter.dispose()
            'End Using
        Catch ex As Exception
            MessageErreur("(Table [" & _TableName & "] " & ex.Message)
            ChargerTable = Nothing
        End Try
    End Function
#end region 


i wish someone have a better solution, because, this is not a solution, to manually edit the content of the dataset designer after each automatic update of the dataset designer.
Posted
Updated 25-Feb-18 21:39pm

1 solution

The fact is that I misunderstood the TableAdapterManager, so I tried to work directly with the table adapter. To do this, I operated a wide replacement of Friend to Public. An operation that was required after each change of the DataSet Designer! And of course, I was wrong.

Last Friday, I found another way: In a Third Party Object, to be used as an entry point, I first tried to redefine the TableAdapterManager's Connection property, but it was not intended for a overload; Given this impasse, I was able to dynamically define each TableAdapter connection using the .net Reflection layer, before asign it to each TableAdapter properties type of TableAdpaterManager (thanks to callbyname one more time). If I did not do it, the connection was the one used to define the Dataset. Today I'm here, and although I now understand what the real solution is, it's the one I use.

Because the real solution is to identify the variable used for each dataset, as chain of connection; then modify it before instantiating the TableAdapterManager and all its TableAdapter properties. Then and only then, the mechanism created by the designer makes sense, because at instantiation, only the value of this chain is recognized. Which also means, that it is essential to lock this instantiation from the beginning to the end, to avoid that multiple requests generates redirection errors. I'm thinking of a pattern of queuing, and asynchronous resolution.

In short, if you know how to know the variable "connection string" used by a dataset, you have won. Of course, we have to choose this variable's name, so we can't do it our own, but the real solution is to get it from the dataset himself. Maybe a xml real.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900