# .NET and More > WPF, WCF, WF >  updating database through WCF

## crater

Hi, I'm brand new to WCF and have followed the MSDN sample of how to load a datagridview with data in a Tier'ed architecture using a WCF service.

The walk through is missing the "how to update your database" though so I set out on my own to try and figure it out. Read allot an failed alot.

I am building winform app that I want in a tier architecture so therefore using the WCF. Beyond that I get confused. 

Here's what I think should work but doesn't. I get a error "(413) Request Entity Too Large" I have read about increasing the Maxmessage size, which I did increase to 200000000.

The following is in my Presentation Layer and the Load event does work, my datagridview does show my data.



```
Public Class Form1

    Dim svchost As New ServiceReference1.Service1Client
    Dim OneData As DataEntity_Tier.OneDataDataSet

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Try
            Me.Validate()
            Me.IDStaffBindingSource.EndEdit()
            svchost.UpdateStaffTable(OneData)
        Catch ex As Exception

        End Try

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        OneDataDataSet.IDStaff.Merge(svchost.GetStaff)
    End Sub
End Class
```

next is code in my IService1 file



```
' NOTE: You can use the "Rename" command on the context menu to change the interface name "IService1" in both code and config file together.
<ServiceContract()>
Public Interface IService1

    <OperationContract()>
    Function GetData(ByVal value As Integer) As String

    <OperationContract()>
    Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType

    ' TODO: Add your service operations here

    <OperationContract()>
    Function GetStaff() As DataEntity_Tier.OneDataDataSet.IDStaffDataTable

    <OperationContract()>
    Sub UpdateStaffTable(ByVal ORds As DataEntity_Tier.OneDataDataSet)

End Interface

' Use a data contract as illustrated in the sample below to add composite types to service operations

<DataContract()>
Public Class CompositeType

    <DataMember()>
    Public Property BoolValue() As Boolean

    <DataMember()>
    Public Property StringValue() As String

End Class
```

And finally the code in Service1.vb



```
' NOTE: You can use the "Rename" command on the context menu to change the class name "Service1" in both code and config file together.
Public Class Service1
    Implements IService1

    Public Function GetData(ByVal value As Integer) As String Implements IService1.GetData
        Return String.Format("You entered: {0}", value)
    End Function

    Public Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType Implements IService1.GetDataUsingDataContract
        If composite Is Nothing Then
            Throw New ArgumentNullException("composite")
        End If
        If composite.BoolValue Then
            composite.StringValue &= "Suffix"
        End If
        Return composite
    End Function

    Public Function GetStaff() As DataEntity_Tier.OneDataDataSet.IDStaffDataTable Implements IService1.GetStaff

        Dim StaffTableAdapter As New DataAccess_Tier.OneDataDataSetTableAdapters.IDStaffTableAdapter

        Return StaffTableAdapter.GetStaff()

    End Function

    Public Sub UpdateStaffTable(ByVal ORds As DataEntity_Tier.OneDataDataSet) Implements IService1.UpdateStaffTable

        Dim ORdata As New DataEntity_Tier.OneDataDataSet
        Dim da As DataAccess_Tier.OneDataDataSetTableAdapters.TableAdapterManager
        da = New DataAccess_Tier.OneDataDataSetTableAdapters.TableAdapterManager

        da.UpdateAll(ORds)

    End Sub

End Class
```

So I think the only relevant information is in the last method of Service1.vb.

So does anyone know what could be going wrong. I have a suspicion that WCF cannot handle passing a dataset but I'm brand new to this so obviously I could be very wrong.

Thanks for any help in advance.

----------


## techgnome

If you're passing the whole dataset, stop... There's really no need... what you should be doing is passing through ONLY CHANGED records from the DATATABLES... at least I think that's how I'd approach it ... which begs the question why does your "UpdateStaff*Table*" take a dataset and update the whole thing? Shouldn't it be taking a DataTable (presumably the Staff table) and just updating that? After all GetStaff only returns a DataTable... 
DataTables have a .GetChanges method that returns a datatable of only the changes (updates, inserts & deletes) ... which comes in handy for sending only small updates back to the server.

-tg

----------


## crater

UpdateStaffTable is a flailing attempt to get my database updated. Originally it was a function passing in the staff table, but that didn't work soooo I changed it to a sub and passed in the dataset, Out of frustration I forgot to change the name.

Passing the dataset is my attempt to make one method to update the entire database, hence the UpdateAll on the tableadapter collection. Just updating the stafftable should only require the Update(ds.datatable) function, which would require allot of functions not to mention trying to keep referential integrity, something the TableAdapterManager does for me.

Yes, I think having separate methods to update each table is good for performance as why update the whole database when only one table has been modified, but I also want a method to update the whole thing for times when we forget to click the save button like in a formclosing event. 

I see now that maybe this can be done through the .GetChanges function of each table, so basically each table is looked at but only data that ismodified is actually passed through. Is this correct? I'm going to look into the .GetChanges function more and fool around with it to see if I can get it to work.

----------


## techgnome

YEs, that's correct... you can even pass in a flag to indicate WHAT changes to get... only updates, only inserts, only deletes, or a combination. By default (no flag) you will get them all. Double check, the DataSet may also have a GetChanges that will get all of the changes from all of the datatables in it. 

-tg

----------


## crater

Thanks for the help Techgnome.
I have it working now, but have a question regarding the following lines:



```
 Dim UpdatedStaffTable As DataTable = OneDataDataSet.IDStaff.GetChanges()

        Dim UpdatedStaffTable As DataEntity_Tier.OneDataDataSet.IDStaffDataTable.GetChanges()
```

#1 works as OneDataDataSet is a member of Form1 and OneDataDataSet resides in the DataEnitity_Tier project

#2 does not work and I know the syntax is even wrong

I am most curious why IDStaff is not a member of DataEntity_Tier.OneDataDataSet when it is a member of OneDataDataSet

Understandably DataTables (ie IDStaff) have a .GetChanges method, but I guess DataTable does not? IE: IDStaffDataTable

I guess I don't understand the difference between the two. Could you explain it or do you need more info.

----------


## crater

going along with the .GetChanges of the DataSet



```
 Dim UpdatedDs As DataSet = OneDataDataSet.GetChanges(DataRowState.Modified)
```

Changing one field even with the flag set returns a message(Entity) too large.

----------

