I have inherited an ArcGIS application that creates a number of access database tables. I'd like to use ArcObjects to convert them to proper geodatabase tables, which I understand to mean simply adding on an ObjectID.

I found an example showing how to do this with Python but couldn't locate one for C#. Could someone point me in that direction, or explain to me what needs to be done?


To save yourself a bit of code you could use the geoprocessor and call DataManagementTools.CopyRows. See also: How to run a geoprocessing tool


// Create the geoprocessor. 
Geoprocessor GP = new Geoprocessor();

// Create the tool process object.
ESRI.ArcGIS.DataManagementTools.CopyRows copyrowsTool = new

// Set parameter values.
copyrowsTool.in_rows = @"D:\St_Johns\data.mdb\roads_table";
copyrowsTool.out_table = @"D:\St_Johns\data.gdb\roads_table";

// Execute the tool. 
GP.Execute(copyrowsTool, null);

As an aside, you can use LINQPad to quickly prototype programs that are more like snippets like this. e.g.:

void Main()
    if (ESRI.ArcGIS.RuntimeManager.ActiveRuntime == null)
    var gp = new Geoprocessor();
    var copyRowsTool = new CopyRows();
    copyRowsTool.in_rows = @"C:\GISData\Database1.mdb\Table1";
    copyRowsTool.out_table = @"C:\GISData\Database1.gdb\Table1";
    gp.Execute(copyRowsTool, null);

LINQPad Screenshot

Add the necessary references (remember to show GAC assemblies) and namespaces in the query properties in LINQPad and off you go!

Image http://img850.imageshack.us/img850/9576/5878c5bb83924c1b9ab7c92.png Image http://img194.imageshack.us/img194/4394/ca8934bca75f47748eb4840.png


  • If you want to use the older version of LINQPad (2.x) that targets .NET 3.5, and you are on a 64-bit OS, you will want to grab the LINQPad for .NET Framework 3.5 - x86 version of LinqPAD from this page. This is because ArcGIS Desktop/Engine is 32-bit and some assemblies (specifically the ESRI.ArcGIS.Version assembly) won't work with the standard LINQPad 2.x executable's build target of AnyCPU on 64-bit OS's. LINQPad 4.x (which targets .NET 4.x) does not seem to have this issue.

  • Also be sure to set "Always use fresh application domains" under Edit-Preferences-Advanced to avoid "COM object that has been separated from its underlying RCW cannot be used" errors when running a query/program a second time.

  • Thanks for your answer, Blah. When I try to run this I get a COM error: "Error HRESULT E_FAIL has been returned...". I'm not really sure how to start debugging this. Do you have any suggestions? – canisrufus Aug 28 '12 at 19:07
  • @canisrufus have you tried this operation inside of an ArcMap session just using it in its toolbox? I'd verify it's working properly with your data there and then move on to any potential C# issues. It's in Data Management>Table. – AHigh Aug 28 '12 at 21:27
  • @AHigh that is a very good idea. – canisrufus Aug 28 '12 at 21:30
  • Are you initializing a license? e.g. ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop); – blah238 Aug 28 '12 at 21:33
  • BTW this worked for me in a test program built in 2 minutes in LINQPad using an Access 2003 database (.mdb). – blah238 Aug 28 '12 at 21:34

I do this... but its probably not the greatest approach

   public bool CreateFileGDB(ref string error, string fullshapefilepath, String shapeFileDirectory, String shapeFileName, string badfields, ShapefileType shapefiletype, string Style )
                string projectionfile = fullshapefilepath.ToUpper().Replace(".SHP", ".PRJ");
                string dbffile = fullshapefilepath.ToUpper().Replace(".SHP", ".DBF");

                ISpatialReference spREF = null;
                if (File.Exists(projectionfile))
                    spREF = MapLibrary.Get().srFactory.CreateESRISpatialReferenceFromPRJFile(projectionfile);
                else  //assume standard coords
                    spREF = MapLibrary.Get().standardSpatialReference;

                string GDBPath = shapeFileDirectory + shapeFileName.Replace(".shp", ".gdb");

                if (!Directory.Exists(GDBPath))
                    string InputFields = badfields;

                    string RequiredFields = string.Empty;
                    if (shapefiletype == ShapefileType.Point || shapefiletype == ShapefileType.Polygon)
                        RequiredFields = US_One_Address_with_Zone_Required_Fields;
                        RequiredFields = US_Streets_with_City_State_ZIP;

                    string[] input = InputFields.Split(splitter);
                    string[] output = RequiredFields.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                    ESRI.ArcGIS.Geodatabase.IWorkspaceFactory pWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
                    string dir = string.Empty;
                    string filename = string.Empty;
                    Util.GetDirectoryFileName(GDBPath, ref dir, ref filename);

                    IWorkspaceName pInShpWorkspaceName = new WorkspaceNameClass() as IWorkspaceName;
                    pInShpWorkspaceName.PathName = shapeFileDirectory;
                    pInShpWorkspaceName.WorkspaceFactoryProgID = "esriCore.ShapefileWorkspaceFactory";
                    IFeatureClassName pFCName = new FeatureClassNameClass() as IFeatureClassName;
                    IDatasetName pShpDatasetName = pFCName as IDatasetName;
                    pShpDatasetName.Name = shapeFileName;//this is your input file 
                    pShpDatasetName.WorkspaceName = pInShpWorkspaceName;
                    IName sourceName = (IName)pFCName;
                    IFeatureClass sourceFeatureClass = (IFeatureClass)sourceName.Open(); //fails
                    IFields sourceFields = sourceFeatureClass.Fields;
                    List<string> fieldnames = GetFieldNames(sourceFields);

                    IWorkspaceName pWorkspaceName = new WorkspaceNameClass() as IWorkspaceName;
                    pWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.FileGDBWorkspaceFactory";
                    pWorkspaceName.PathName = GDBPath; //output file 
                    IFeatureClassName pOutputFC = new FeatureClassNameClass();
                    IDatasetName pDataSetName = pOutputFC as IDatasetName;
                    pDataSetName.WorkspaceName = pWorkspaceName;
                    pDataSetName.Name = "Streets";
                    IFeatureDataConverter pShpToFc = new FeatureDataConverterClass();

                    for (int i = 0; i < input.Length; i++)
                        RenameColumn(sourceFields, input[i], output[i]);

                    List<string> newfieldnames = GetFieldNames(sourceFields);

                    if(shapefiletype == ShapefileType.Point)
                        IGeometryDef def = Create_IGeometryDef(spREF, esriGeometryType.esriGeometryPoint);
                        pShpToFc.ConvertFeatureClass(pFCName, null, null, pOutputFC, def, sourceFields, "", 1000, 0);
                    else if(shapefiletype == ShapefileType.Polygon)
                        IGeometryDef def = Create_IGeometryDef(spREF, esriGeometryType.esriGeometryPolygon);
                        pShpToFc.ConvertFeatureClass(pFCName, null, null, pOutputFC, def, sourceFields, "", 1000, 0);
                    else if (shapefiletype == ShapefileType.Polyline)
                        IGeometryDef def = Create_IGeometryDef(spREF, esriGeometryType.esriGeometryPolyline);
                        pShpToFc.ConvertFeatureClass(pFCName, null, null, pOutputFC, def, sourceFields, "", 1000, 0);
                        pShpToFc.ConvertFeatureClass(pFCName, null, null, pOutputFC, null, sourceFields, "", 1000, 0);

                return true;
  • Thanks for your answer. I think I'm going to go with Blah's more parsimonious approach. – canisrufus Aug 28 '12 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.