Results 1 to 5 of 5

Thread: Update from Dataset without original adaptor?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Dec 2012
    Posts
    136

    Question Update from Dataset without original adaptor?

    I'm playing with VB2010 express and MS SQLServer Express

    I've made a small app that uses a Module function to retrieve a dataset then I mess around and change some values in the dataset. Now I want to update the database but all the examples I can find use the original dataadapter to do the update. My original dataadapter is gone so how do I do an update? I can't see any way to create a new datadapter without also creating a new dataset...

    Pseudo code so you know what I mean (don't have program handy so don't sweat apparent mistakes in coding)

    Code:
    Function DoQuery(ByRef myDataset as Dataset, myQuery as string) as boolean
    
    	Dim result As Boolean = false
    
    	myConnString = GetConnString()
    
    	Using myConn as new SqlConnection(myConnString)
    		myConn.Open()
    		Using myAdapter as new SqlDataAdapter(myQuery,myConn)
    			myConn.Close()
    			myAdapter.Fill(myDataset)
    			result = true
    		End Using
    	End Using
    	return result
    End Function
    Any ideas? Or do I have to drop "Using" and make the adapter and dataset global?

    Edit: Just realized... I should give the dataadapter the same scope as the dataset and pass both byref to the DoQuery.. I think. Hmmm, maybe I'll just do everything on each form since after the dataset and adapter there's not much more to doing the queries and I'm not saving a whole lot of coding by using a function in a module.
    Last edited by pmeloy; May 31st, 2014 at 12:37 PM.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Update from Dataset without original adaptor?

    Firstly, you shouldn't be passing anything ByRef. With classes, you only pass ByRef if you intend to assign a new value to the parameter inside the method and you want that change to affect the caller as well. If you're not doing that, which is a minority of cases, then you don't pass ByRef. ByVal is the default for good reason.

    As for your question, you certainly can pass in the DataSet and the data adapter but creating a new data adapter is completely unrelated to the DataSet so you certainly can create a new one. If you want to create new data adapter then just create a new data adapter. It's that simple.

    While it generally makes sense to use the same data adapter to retrieve and save data when your data access code is mixed up with your business logic and presentation code, i.e. all your code is in the form, it's very common for data access code to be extracted out into its own classes or even its own project. In such cases, you will most likely not be using the same data adapter in both cases. That's fine; just write a method that creates, configures and returns a data adapter and then call that method once when you need to get data and once when you need to save the changes. It won't be the same data adapter object but it will contain all the same SQL code and that's what does the work of saving the data. Here's a simple example:
    vb.net Code:
    1. Public Function GetData() As DataTable
    2.     Using adapter = GetDataAdapter()
    3.         'Create a new table.
    4.         Dim table As New DataTable
    5.  
    6.         'Populate the table with data from the database.
    7.         adapter.Fill(table)
    8.  
    9.         'Return the populated table to the caller.
    10.         Return table
    11.     End Using
    12. End Function
    13.  
    14. Public Sub SaveChanges(table As DataTable)
    15.     'The data adapter saves the changes and the command builder generates the INSERT, UPDATE and DELETE commands to do it.
    16.     Using adapter = GetDataAdapter(),
    17.           builder = New SqlCommandBuilder(adapter)
    18.         'Escape all column names in case of reserved words or special characters.
    19.         builder.QuotePrefix = "["
    20.         builder.QuoteSuffix = "]"
    21.  
    22.         'Save the changes back to the database.
    23.         adapter.Update(table)
    24.     End Using
    25. End Sub
    26.  
    27. Private Function GetDataAdapter() As SqlDataAdapter
    28.     'Create a new data adapter with a query and a connection string.
    29.     Dim adapter As New SqlDataAdapter("SELECT * FROM MyTable",
    30.                                       ConfigurationManager.ConnectionStrings("MyConnectionString").ConnectionString)
    31.  
    32.     'Retrieve primary key information from the database to allow a command builder to generate UPDATE and DELETE commands.
    33.     adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
    34.  
    35.     Return adapter
    36. End Function
    Note that the calling code never sees the data adapter or any of the other data access objects. It simply asks for data and receives it in a DataTable, then passes that DataTable back and asks that the changes be saved. What happens inside the data access module is of no concern to that calling code.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Dec 2012
    Posts
    136

    Re: Update from Dataset without original adaptor?

    Ah, that's what was throwing me off. I never saw an adapter created without it also doing a new query. That made me think I couldn't use update with an existing dataset because the adapter already had a different one.

    Would I be correct to assume that the new adapter's query has to be the same as the one used for the existing dataset? Or can I just select one row from (each) table in order to get the schema then apply the update? Hmmm, it seems to me it would need all the same rows in order to match the updated rows.

    So if the original query was

    Code:
    SELECT persons.id, persons.name, persons.title_id, titles.title 
    FROM persons,titles
    WHERE titles.id = persons.title_id
    then I'd have to pass that same query to GetAdapter() for the updating adapter so it has the same data?

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Update from Dataset without original adaptor?

    The data adapter doesn't need a query at all if it's going to be saving changes and not retrieving data. When you call Fill it's the SelectCommand that gets executed and when you call Update it's the InsertCommand, UpdateCommand and DeleteCommand that get executed as required. If you create those three commands yourself then you don't need the SelectCommand at all to save data.

    I included the SelectCommand in this case because that's what the command builder uses as a basis for generating the other three. Only the columns specified in the SelectCommand will be included in the InsertCommand and the UpdateCommand so any columns that you want to be able to save must be specified in the query.

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Dec 2012
    Posts
    136

    Re: Update from Dataset without original adaptor?

    I was playing with this and realized the SaveChanges scheme never calls .fill() so the select command is never executed but that .MissingSchemaAction is used. So I supplied a select string with all the tables from the original query and everything worked great.

    I'll try again but this time only use the tables I'm actually updating (my dataset has four tables but only one actually has data changed).

    Thanks very much for the help. Next I have to figure out the permissions scheme in sqlserver express. In mysql and postgresql the permissions setup is pretty straightforward but sqlserver's is confusing. Lots of reading ahead 8)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width