Select to view content in your preferred language

How to get a ADO.Net Datatable from a Feature Layer?

2909
5
12-08-2011 09:13 AM
KevinOrcutt
Emerging Contributor
Howdy All,
    The title kinda says it all or more correctly asks it all...  I've have been pulling my hair out trying to get either a feature layers table or a particular selected feature attributes into a datatable so that I can display it in a datagridview...  The couple of examples that I've found are either incomplete and won't compile, or are for Arc Engine...  My environment is:

Current Environment:
ArcMap 10.0 Service Pack 3, ArcInfo license level
ArcObjects SDK, Service Pack 1
Visual Studio 2010 Professional, Service Pack 1
VB.Net

Working on an ArcMap Add-In. 
In the project I have a form in which the users will "cycle" through the selected features of a layer and edit a few attributes as needed.  I would like to present the sttributes via a datagridview.  which is more preferrable over individual attributes in a textbox.

Any clues???

Thanks in advance,
Kevin Orcutt
0 Kudos
5 Replies
AlexanderGray
Honored Contributor
I have done this in the past by writing my own data adapter.  If you can cycle through your feature layer, you I assume you have some sort of cursor.  A cursor has a list of fields.  These fields have properties such as data type, length, etc.  .Net datatables also have fields, called columns that are of different type.  So create a new datatable, cycle through the fields and for each one create a column in the datatable with equivalent types.  The cycle through the cursor, adding a row in the datatable for each row in the cursor, and set each column of the row to the value of the corresponding field in the cursor row.  The bind the datatable to the datagridview.  If the user is going to edit the datagridview, you are going to need to write the code to put the changes back into the featureclass.

It is a little tedious and the performance is lackluster but it works.  Watch out for the nullable property on the field.  If the cursor is created with an outer-join query, the field reports the nullable value of the base table, which could not allow null value and could very well have null values in the cursor for that field (due to the outer-join.)  I remember getting snagged by that because we created a column that doesn't all null values, then tried to cram null values into it and got an exception.
0 Kudos
JamesCrandall
MVP Alum
Sure.  Have a look/download one of my uploads to the Code Gallery:

http://resources.arcgis.com/gallery/file/arcobjects-net-api/details?entryID=675318D8-1422-2418-8814-...

Let me know if you need additional help!

Here's the relevent code from the sample.  Returns an ADO.NET DataTable:

 Public Function ConvertToADONETDataTableFromLayer(ByVal inLayer As IFeatureLayer) As DataTable

        Try

            Dim tmpDT As New DataTable("tmpDT")
            Dim column As DataColumn

            Dim pTable As ITable = inLayer.FeatureClass
            Dim pFields As IFields = pTable.Fields
            Dim pCur As ICursor = pTable.Search(Nothing, False)

            For c = 0 To pCur.Fields.FieldCount - 1
                column = New DataColumn()
                column.ColumnName = (pFields.Field(c).Name)
                If pFields.Field(c).Type = esriFieldType.esriFieldTypeString Then
                    column.DataType = System.Type.GetType("System.String")
                ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeInteger Then
                    column.DataType = System.Type.GetType("System.Int32")
                ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeDouble Then
                    column.DataType = System.Type.GetType("System.Double")
                ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeDate Then
                    column.DataType = System.Type.GetType("System.DateTime")
                ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeSingle Then
                    column.DataType = System.Type.GetType("System.Single")
                ElseIf pFields.Field(c).Type = esriFieldType.esriFieldTypeBlob Then
                    column.DataType = System.Type.GetType("System.Byte")
                End If


                column.ReadOnly = False
                tmpDT.Columns.Add(column)
            Next

            Dim pRow As IRow = pCur.NextRow
            Dim newRow As DataRow

            Do Until pRow Is Nothing

                newRow = tmpDT.NewRow()
                newRow.BeginEdit()
                For cols = 0 To pCur.Fields.FieldCount - 1
                    newRow(cols) = pRow.Value(pRow.Fields.FindField(pFields.Field(cols).Name))
                Next
                newRow.EndEdit()
                tmpDT.Rows.Add(newRow)
                tmpDT.AcceptChanges()

                pRow = pCur.NextRow

            Loop

            Return tmpDT

        Catch ex As Exception
            MsgBox(ex.ToString)
            Return Nothing
        End Try

    End Function
James
0 Kudos
JamesCrandall
MVP Alum
Kevin,

I just realized that you commented on the download page of the CodeGallery where I make the vbproj and class available.  To answer your question, after you download it:

1. Extract the files.
2. Disregard the vbproj file.  After the new Code Gallery switch, this seems to have gotten corrupted.
3. Not a big deal, in your current assembly/vb project's Solution Explorer window, right click the project and choose "Add", then "Existing Item".
4. Navigate to where you extracted the downloaded files and select the DatTabConverter class file.  This will add the code to your project.

You can simply reference the class to access the ConvertToADONETDataTableFromLayer function, or just copy and paste into your own classes.

Good luck and let me know if you need more assistance.  Thanks for downloading!
0 Kudos
KevinOrcutt
Emerging Contributor
Hello James,
    Thank you for your input.  I saw your response over on the page with your download, and figured out what to do...   Works great now...  One would figure that ESRI would have something along these lines, but I couldn't find it...

Thanks again,
Kevin Orcutt
0 Kudos
JamesCrandall
MVP Alum
Hello James,
    Thank you for your input.  I saw your response over on the page with your download, and figured out what to do...   Works great now...  One would figure that ESRI would have something along these lines, but I couldn't find it...

Thanks again,
Kevin Orcutt


Hey, that's great to hear! 

The majority of my projects/implementations nowadays is about spatial and non-spatial database integration, so that means lots and lots of ADO.NET and Transact-SQL.  Also, and this is just from my own experience, building GIS solutions with an n-Tier architecture/approach has been very beneficial and I'd recommend looking into it.  Basically, I just veiw/treat ArcGIS as any other UI (but one that comes with very powerful spatial data processing) -- thus having the n-Tier architecture allows me to integrate other layers and databases.

Spend some time over at MSDN and look into some of the patterns & practices approaches to software design.  This article is a bit dated but the basic ideas still apply:

http://msdn.microsoft.com/en-us/library/ms973279.aspx
0 Kudos