<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Optimizing discovery of all layers, datasets, tables, relationships in ArcGIS Pro SDK Questions</title>
    <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1632863#M13056</link>
    <description>&lt;P&gt;According to the &lt;A href="https://learn.microsoft.com/en-us/visualstudio/ide/reference/convert-foreach-linq?view=vs-2022" target="_self"&gt;MSDN&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;LINQ syntax is typically less efficient than a foreach loop. It's good to be aware of any performance tradeoff that might occur when you use LINQ to improve the readability of your code.&lt;/EM&gt;&lt;/P&gt;</description>
    <pubDate>Mon, 14 Jul 2025 15:11:32 GMT</pubDate>
    <dc:creator>Aashis</dc:creator>
    <dc:date>2025-07-14T15:11:32Z</dc:date>
    <item>
      <title>Optimizing discovery of all layers, datasets, tables, relationships</title>
      <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1632538#M13050</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am curious if there is anything to do to optimize discovery of the layers in a geodatabase.&amp;nbsp; Basically I am creating a tree of the datasets, layers, and other tables - much like ArcCatalog would.&amp;nbsp; Here is what I have now. I am wondering if using LINQ may offer performance boosts or if there are any other suggestions to speed up the method.&lt;/P&gt;&lt;P&gt;Thanks in advance, -Bil&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;internal int GetEsriDatasetMap(&lt;BR /&gt;int message_id,&lt;BR /&gt;bool include_tables,&lt;BR /&gt;bool layer_names_only)&lt;BR /&gt;{&lt;BR /&gt;// Get all the feature datasets and the classes in them.&lt;/P&gt;&lt;P&gt;// ESRI databases have proper datasets containing feature classes as well&lt;BR /&gt;// as improper datasets which are feature classes with no enclosing dataset.&lt;BR /&gt;// Find all the proper datasets, verify their CRS is WGS84 and&lt;BR /&gt;// if so collect their feature classes. Then find all the improper datasets&lt;BR /&gt;// which are feature classes without an enclosing dataset. These also&lt;BR /&gt;// have a CRS which must be WGS84.&lt;BR /&gt;// Feature classes within an enclosing dataset have the same CRS as the dataset.&lt;/P&gt;&lt;P&gt;int error = -1;&lt;/P&gt;&lt;P&gt;//EsriMessageBox.DisplayMessage("Attach debugger bish");&lt;/P&gt;&lt;P&gt;if (m_dataset_map == null) {&lt;BR /&gt;&amp;nbsp; &amp;nbsp;m_dataset_map = new EsriDatasetMap();&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;// Check to see if this has already been done&lt;BR /&gt;if (m_dataset_map.Count &amp;gt; 0)&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp;error = 0;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;EsriLogger.Log("Datasets already figured. Moving along.");&lt;BR /&gt;}&lt;BR /&gt;else&lt;BR /&gt;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp;string empty_dataset_name = SEE_NO_DATASET;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;List&amp;lt;String&amp;gt; all_layer_names = new List&amp;lt;string&amp;gt;();&lt;BR /&gt;&amp;nbsp; &amp;nbsp;List&amp;lt;string&amp;gt; layer_names_in_datsets = new List&amp;lt;string&amp;gt;();&lt;BR /&gt;&amp;nbsp; &amp;nbsp;string layer_name = "";&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;IReadOnlyList&amp;lt;FeatureClassDefinition&amp;gt; featureClassDefinitions =&amp;nbsp; &amp;nbsp;geodb.GetDefinitions&amp;lt;FeatureClassDefinition&amp;gt;();&lt;BR /&gt;&amp;nbsp; &amp;nbsp;IEnumerable&amp;lt;Definition&amp;gt; featureClasses = featureClassDefinitions;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;foreach (var fc in featureClasses)&lt;BR /&gt;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; layer_name = fc.GetName();&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; DatasetType fc_dst = fc.DatasetType;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; all_layer_names.Add(layer_name);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; m_layer_names.Add(layer_name);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; //EsriLogger.Log("Layer name is: " + layer_name + ". Type is: " + fc_dst);&lt;BR /&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;if (include_tables)&lt;BR /&gt;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; IReadOnlyList&amp;lt;TableDefinition&amp;gt; tableDefinitions = geodb.GetDefinitions&amp;lt;TableDefinition&amp;gt;();&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; IEnumerable&amp;lt;Definition&amp;gt; tables = tableDefinitions;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; foreach (var table in tables)&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;layer_name = table.GetName();&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;DatasetType td = table.DatasetType;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;m_layer_names.Add(layer_name);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//EsriLogger.Log("Table name is: " + layer_name + ". Type is: " + td);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;BR /&gt;&amp;nbsp; }&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;error = 0;&lt;BR /&gt;&amp;nbsp; &amp;nbsp;m_layer_names.Sort();&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;// Sometime after release 2.2 dataset definitions were added making it possible to&lt;BR /&gt;&amp;nbsp; &amp;nbsp;// get the layers in their respective datasets instead of flattening all of thrm under&lt;BR /&gt;&amp;nbsp; &amp;nbsp;// one dataset.&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;// Get feature datasets&lt;BR /&gt;&amp;nbsp; &amp;nbsp;IReadOnlyList&amp;lt;Definition&amp;gt; feature_datasets_list = geodb.GetDefinitions&amp;lt;FeatureDatasetDefinition&amp;gt;();&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;// Get all the feature classes under their respective dataset folders and package them up&lt;BR /&gt;&amp;nbsp; &amp;nbsp;// to send back to SGXP.&lt;BR /&gt;&amp;nbsp; &amp;nbsp;foreach (var feature_dataset in feature_datasets_list)&lt;BR /&gt;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; EsriLogger.Log("feature_dataset name is: " + feature_dataset.GetName() + ". Type is: " +&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; feature_dataset.GetType());&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; var defsInDataset = geodb.GetRelatedDefinitions(feature_dataset,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DefinitionRelationshipType.DatasetInFeatureDataset);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;String&amp;gt; classes = new List&amp;lt;string&amp;gt;();&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; bool ds_has_features = false;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; foreach (var def in defsInDataset)&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; { //Or use LINQ .Where( d =&amp;gt; d.DatasetType ...&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EsriLogger.Log("def name is: " + def.GetName() + ". Type is: " + def.GetType());&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (def.DatasetType == DatasetType.FeatureClass)&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; classes.Add(def.GetName());&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; m_layer_names.Add(def.GetName());&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ds_has_features = true;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; layer_names_in_datsets.Add(def.GetName());&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if (ds_has_features)&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;m_dataset_map.Add(feature_dataset.GetName(), classes);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;BR /&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;// Add all features not in datasets or just tables&lt;BR /&gt;&amp;nbsp; &amp;nbsp;List&amp;lt;string&amp;gt; layers_not_in_datasets = new List&amp;lt;string&amp;gt;();&lt;BR /&gt;&amp;nbsp; &amp;nbsp;foreach (var lyr_name in m_layer_names)&lt;BR /&gt;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if (!layer_names_in_datsets.Contains(lyr_name))&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;layers_not_in_datasets.Add(lyr_name);&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;BR /&gt;&amp;nbsp; &amp;nbsp;}&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;if (layers_not_in_datasets.Count &amp;gt; 0)&lt;BR /&gt;&amp;nbsp; &amp;nbsp;{&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; m_dataset_map.Add(empty_dataset_name, layers_not_in_datasets);&lt;BR /&gt;&amp;nbsp; &amp;nbsp;}&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;// Pack up the byte stream and send the result via IPC&lt;BR /&gt;int command = SEE_DATASET_MAP_POPULATED;&lt;BR /&gt;int total_len = DEFAULT_BUFLEN;&lt;BR /&gt;int offset = EsriUtil.CreateMessageHeader(out byte[] message, total_len, command, message_id, error);&lt;/P&gt;&lt;P&gt;// serialize the map.&lt;BR /&gt;EsriUtil.AddInt(m_dataset_map.Count, ref message, ref offset);&lt;/P&gt;&lt;P&gt;foreach (var dm in m_dataset_map) {&lt;BR /&gt;// name of the dataset&lt;BR /&gt;EsriUtil.AddStringWithLength(dm.Key, ref message, ref offset);&lt;BR /&gt;// number of layers in this dataset&lt;BR /&gt;EsriUtil.AddInt(dm.Value.Count, ref message, ref offset);&lt;/P&gt;&lt;P&gt;foreach (var layer in dm.Value) {&lt;BR /&gt;// layer names in this dataset&lt;BR /&gt;EsriUtil.AddStringWithLength(layer, ref message, ref offset);&lt;BR /&gt;}&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;EsriManager.Instance.SendMessage(message);&lt;BR /&gt;return error;&lt;BR /&gt;}&lt;/P&gt;</description>
      <pubDate>Fri, 11 Jul 2025 18:32:32 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1632538#M13050</guid>
      <dc:creator>BillSmith</dc:creator>
      <dc:date>2025-07-11T18:32:32Z</dc:date>
    </item>
    <item>
      <title>Re: Optimizing discovery of all layers, datasets, tables, relationships</title>
      <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1632863#M13056</link>
      <description>&lt;P&gt;According to the &lt;A href="https://learn.microsoft.com/en-us/visualstudio/ide/reference/convert-foreach-linq?view=vs-2022" target="_self"&gt;MSDN&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;LINQ syntax is typically less efficient than a foreach loop. It's good to be aware of any performance tradeoff that might occur when you use LINQ to improve the readability of your code.&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 14 Jul 2025 15:11:32 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1632863#M13056</guid>
      <dc:creator>Aashis</dc:creator>
      <dc:date>2025-07-14T15:11:32Z</dc:date>
    </item>
    <item>
      <title>Re: Optimizing discovery of all layers, datasets, tables, relationships</title>
      <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1633033#M13061</link>
      <description>&lt;P&gt;You're already implementing a well-structured method for collecting and mapping datasets, feature classes, and tables in a geodatabase.&lt;/P&gt;&lt;P&gt;While LINQ doesn’t inherently make things faster, it makes &lt;STRONG&gt;logic more concise and sometimes avoids unnecessary list traversals&lt;/STRONG&gt;, which helps performance indirectly.&lt;/P&gt;&lt;P&gt;For example, this block:&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;foreach (var lyr_name in m_layer_names)
{
   if (!layer_names_in_datsets.Contains(lyr_name))
   {
      layers_not_in_datasets.Add(lyr_name);
   }
}&lt;/LI-CODE&gt;</description>
      <pubDate>Tue, 15 Jul 2025 04:49:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1633033#M13061</guid>
      <dc:creator>SumitMishra_016</dc:creator>
      <dc:date>2025-07-15T04:49:49Z</dc:date>
    </item>
    <item>
      <title>Re: Optimizing discovery of all layers, datasets, tables, relationships</title>
      <link>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1633372#M13065</link>
      <description>&lt;P&gt;Thank you.&amp;nbsp; I am trying a LINQ implementation to get performance numbers.&amp;nbsp; I only have to do this once, upon initial connection, so subsequent cached results are very fast.&amp;nbsp; It's just that this is the long tentpole in our performance of connecting.&amp;nbsp; If its the best we can do, so be it!&lt;/P&gt;</description>
      <pubDate>Wed, 16 Jul 2025 00:26:04 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-sdk-questions/optimizing-discovery-of-all-layers-datasets-tables/m-p/1633372#M13065</guid>
      <dc:creator>BillSmith</dc:creator>
      <dc:date>2025-07-16T00:26:04Z</dc:date>
    </item>
  </channel>
</rss>

