I am trying to get a list of the fields in a feature inside the project default geodatabase.
what is the c# pro sdk equivalent of the python below?
for lyr in m.listLayers():
if lyr.name == "layer":
field_names = []
fields = arcpy.ListFields(lyr)
for field in fields:
field_names.append(field.name)
Do i have to go through the geodatabse API with a feature definition to get that list? like below. or is there a shorter or more prefered way?
using (Geodatabase fileGeodatabase = new Geodatabase(new FileGeodatabaseConnectionPath((uri))))
using (FeatureClass featureClass = fileGeodatabase.OpenDataset<FeatureClass>(matchLyr))
{
FeatureClassDefinition LyrDefinition = featureClass.GetDefinition();
IReadOnlyList<Field> fields = LyrDefinition.GetFields();
List<string> fieldList = new List<string>();
foreach (var fld in fields)
{
fieldList.Add(fld.Name);
Debug.WriteLine(fld.Name);
}
return fieldList;
}
Solved! Go to Solution.
I was confused by this at first too. The statement
return matchField
exits the delegate passed to QueuedTask.Run(). You still have to return a value from the GetFieldList() function.
You *could* say
return await ArcGIS.Desktop.Framework.ThreadingTasks.QueuedTask.Run(...
However my colleague Charles Macleod recommended the following:
public static async Task<string> GetFieldList(…
return await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
And then await GetFieldList() in the calling function.
You can actually call Geodatabase.GetDefinition<FeatureClassDefinition>() to go directly from the file geodatabase to the definition without incurring the overhead of opening the table. Other than that, this code is the correct way to get the field list.
--Rich
Thanks Rich it seems to be working but im getting an error "not all code paths return a value". Im confused if it runs the task, gets the table definition, gets the field list, adds the field name to a list, intersects 2 lists to get the first matching value, then returns the matching value, what other code path would there be?
public static async Task<string> GetFieldList(string layer, string projGDBPath, List<string> fieldOneOptions)
{
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (Geodatabase fileGeodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(projGDBPath))))
using (FeatureClassDefinition featureClass = fileGeodatabase.GetDefinition<FeatureClassDefinition>(layer))
{
IReadOnlyList<Field> fields = featureClass.GetFields();
List<string> fieldList = new List<string>();
foreach (var fld in fields)
{
fieldList.Add(fld.Name)
}
string matchField = fieldOneOptions.Intersect(fieldList).FirstOrDefault().ToString();
return matchField;
}
});
}
I was confused by this at first too. The statement
return matchField
exits the delegate passed to QueuedTask.Run(). You still have to return a value from the GetFieldList() function.
You *could* say
return await ArcGIS.Desktop.Framework.ThreadingTasks.QueuedTask.Run(...
However my colleague Charles Macleod recommended the following:
public static async Task<string> GetFieldList(…
return await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
And then await GetFieldList() in the calling function.
awaiting GetFieldList() from Charles worked great. Thanks.
If you already have the layer you can also do something similar to the following
IReadOnlyList<ArcGIS.Core.Data.Field> fields = null;
List<string> fieldList = new List<string>();
await QueuedTask.Run(() =>
{
ArcGIS.Core.Data.Table table = theFeatureLayer.GetTable();
if (table != null)
{
ArcGIS.Core.Data.TableDefinition def = table.GetDefinition();
fields = def.GetFields();
foreach (var fld in fields)
{
fieldList.Add(fld.Name);
Debug.WriteLine(fld.Name);
}
}
});
You still end up looking at the feature layer / table definition, but because you have the layer you don't need the additional Geodatabase object.