Query a feature layer (SQL)

Learn how to execute a SQL query to return features from a feature layer based on spatial and attribute criteria.

query a feature layer

A feature layer can contain a large number of features stored in ArcGIS. You can query a layer to access a subset of its features using any combination of spatial and attribute criteria. You can control whether or not each feature's geometry is returned, as well as which attributes are included in the results. Queries allow you to return a well-defined subset of your hosted data for analysis or display in your ArcGIS Runtime app.

In this tutorial, you'll write code to perform SQL queries that return a subset of features in the LA County Parcel feature layer (containing over 2.4 million features). Features that meet the query criteria are selected in the map.

Prerequisites

Before starting this tutorial, you should:

  • Have an ArcGIS account and an API key to access ArcGIS services. If you don't have an account, sign up for free.
  • Ensure your development environment meets the system requirements.

Optionally, you may want to install the ArcGIS Runtime SDK for .NET to get access to project templates in Visual Studio (Windows only) and offline copies of the NuGet packages.

Steps

Open a Visual Studio solution

  1. To start the tutorial, complete the Display a map tutorial or download and unzip the solution.

  2. Open the .sln file in Visual Studio.

  3. If you downloaded the solution project, set your API key.

    An API Key enables access to services, web maps, and web scenes hosted in ArcGIS Online.

    If necessary, set the API Key.
    1. Go to your developer dashboard to get your API key. For these tutorials, use your default API key. It is scoped to include all of the services demonstrated in the tutorials.

    2. In Visual Studio, in the Solution Explorer, click App.xaml.cs.

    3. In the App class, add an override for the OnStartup() function to set the ApiKey property on ArcGISRuntimeEnvironment.

      App.xaml.cs
      Use dark colors for code blocks
                                              
      Add line.Add line.Add line.Add line.Add line.Add line.Add line.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      //   Copyright 2021 Esri
      //   Licensed under the Apache License, Version 2.0 (the "License");
      //   you may not use this file except in compliance with the License.
      //   You may obtain a copy of the License at
      //
      //   https://www.apache.org/licenses/LICENSE-2.0
      //
      //   Unless required by applicable law or agreed to in writing, software
      //   distributed under the License is distributed on an "AS IS" BASIS,
      //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      //   See the License for the specific language governing permissions and
      //   limitations under the License.
      
      using System;
      using System.Collections.Generic;
      using System.Configuration;
      using System.Data;
      using System.Linq;
      using System.Threading.Tasks;
      using System.Windows;
      
      namespace DisplayAMap
      {
          /// <summary>
          /// Interaction logic for App.xaml
          /// </summary>
      
          public partial class App : Application
          {
      
              protected override void OnStartup(StartupEventArgs e)
              {
                  base.OnStartup(e);
                  // Note: it is not best practice to store API keys in source code.
                  // The API key is referenced here for the convenience of this tutorial.
                  Esri.ArcGISRuntime.ArcGISRuntimeEnvironment.ApiKey = "YOUR_API_KEY";
              }
      
          }
      }
      

If developing with Visual Studio for Windows, ArcGIS Runtime for .NET provides a set of project templates for each of the supported .NET platforms. These templates provide all of the code needed for a basic Model-View-ViewModel (MVVM) app. You need to install the ArcGIS Runtime for .NET Visual Studio Extension to add the templates to Visual Studio (Windows only). See Install and set up for details.

Update the tutorial name used in the project (optional)

The Visual Studio solution, project, and the namespace for all classes currently use the name DisplayAMap. Follow the steps below if you prefer the name to reflect the current tutorial. These steps are not required, your code will still work if you keep the original name.

The tutorial instructions and code use the name QueryAFeatureLayerSQL for the solution, project, and namespace. You can choose any name you like, but it should be the same for each of these.

  1. Update the name for the solution and the project.

    • In Visual Studio, in the Solution Explorer, right-click the solution name and choose Rename. Provide the new name for your solution.
    • In the Solution Explorer, right-click the project name and choose Rename. Provide the new name for your project.
  2. Rename the namespace used by classes in the project.

    • In the Solution Explorer, expand the project node.
    • Double-click MapViewModel.cs in the Solution Explorer to open the file.
    • In the MapViewModel class, double-click the namespace name (DisplayAMap) to select it, and then right-click and choose Rename....
    • Provide the new name for the namespace.
    • Click Apply in the Rename: DisplayAMap window that appears in the upper-right of the code window. This will rename the namespace throughout your project.
  3. Build the project.

    • Choose Build > Build solution (or press <F6>).

Steps

Add UI for selecting a predefined query expression

To make performing a query on a feature layer more flexible, add a ComboBox control to present a list of predefined attribute queries for the parcels dataset. While editing this file, also modify the MapView control to bind its SelectionProperties to a property in the view model (so you can set the color used to display selected parcels).

  1. In the Visual Studio > Solution Explorer, double-click the MainWindow.xaml file to open it.

  2. Add XAML that defines a ComboBox control and its behavior.

    • The control is positioned above the map view in the upper-left corner.
    • A list of ComboBoxItems shows predefined expression choices.
    • The first combo box item instructs the user to choose an expression that will be selected when the app initializes.
    • Changes in the selected expression will be handled by the QueryComboBox_SelectionChanged event handler.

    Also modify the MapView control to bind the SelectionProperties property.

    MainWindow.xaml
    Use dark colors for code blocks
                                            
    Change lineChange lineChange lineAdd line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    <Window x:Class="QueryAFeatureLayerSQL.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:QueryAFeatureLayerSQL"
            xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
    
        <Window.Resources>
            <local:MapViewModel x:Key="MapViewModel" />
        </Window.Resources>
    
        <Grid>
    
            <esri:MapView x:Name="MainMapView"
                          Map="{Binding Map, Source={StaticResource MapViewModel}}"
                          SelectionProperties="{Binding SelectionProps, Source={StaticResource MapViewModel}}"/>
    
            <ComboBox x:Name="QueryComboBox"
                      SelectionChanged="QueryComboBox_SelectionChanged"
                      SelectedIndex="0"
                      SelectedValuePath="Content"
                      HorizontalAlignment="Left" VerticalAlignment="Top"
                      Margin="20" Padding="30,10">
                <ComboBoxItem>Choose a SQL where clause</ComboBoxItem>
                <ComboBoxItem>UseType = 'Government'</ComboBoxItem>
                <ComboBoxItem>UseType = 'Residential'</ComboBoxItem>
                <ComboBoxItem>UseType = 'Irrigated Farm'</ComboBoxItem>
                <ComboBoxItem>TaxRateArea = 10853</ComboBoxItem>
                <ComboBoxItem>TaxRateArea = 10860</ComboBoxItem>
                <ComboBoxItem>Roll_LandValue &gt; 1000000</ComboBoxItem>
                <ComboBoxItem>Roll_LandValue &lt; 1000000</ComboBoxItem>
            </ComboBox>
    
        </Grid>
    
    </Window>
  3. In the section for the combo box you just added, right-click on the name of the event handler text ("QueryComboBox_SelectionChanged") and choose Go To definition from the context menu. Visual Studio will open the MapWindows.xaml.cs file with the stub for the new QueryComboBox_SelectionChanged() function.

Add code to call the selected query for the current map extent

When the user chooses an expression in the combo box, call a function to execute the query.

The function to execute the query takes three arguments: the ID for the layer to query (string), a SQL expression that defines attribute criteria (string), and the area of the MapView currently being viewed (Envelope).

  1. In the QueryComboBox_SelectionChanged() function: modify the method signature to add the async keyword.

    MainWindow.xaml.cs
    Use dark colors for code blocks
                                                                                      
    Change lineChange line
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    using Esri.ArcGISRuntime.Geometry;
    using Esri.ArcGISRuntime.Mapping;
    
    namespace QueryAFeatureLayerSQL
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                MapPoint mapCenterPoint = new MapPoint(-118.805, 34.027, SpatialReferences.Wgs84);
                MainMapView.SetViewpoint(new Viewpoint(mapCenterPoint, 100000));
            }
    
            private async void QueryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
    
                // Since the first choice in the combo box are instructions for the app
                // (not actual SQL where clause syntax), ignore it.
                if (QueryComboBox.SelectedIndex != 0)
                {
                    // Get the view model using the ID given for the static resource in the XAML.
                    MapViewModel currentMapViewModel = this.FindResource("MapViewModel") as MapViewModel;
    
                    // Get the current view point extent.
                    Envelope currentExtent = MainMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry as Envelope;
    
                    // Define the string ID for the feature layer to query.
                    string featureLayerId = "Parcels";
    
                    // Define the SQL query where clause to apply to the feature layer.
                    // Several SQL query strings were pre-populated in the combo box.
                    // This line of code gets the selected choice from the combo box
                    // and assigns it to the SQL query string.
                    string sqlQuery = QueryComboBox.SelectedValue.ToString();
    
                    // Call the function in the view model that queries a feature layer. Pass in the:
                    // (1) feature layer ID
                    // (2) specific SQL syntax for the feature layer
                    // (3) current map extent
                    await currentMapViewModel.QueryFeatureLayer(featureLayerId, sqlQuery, currentExtent);
                }
    
            }
    
        }
    
    }
    
  2. Again, in the QueryComboBox_SelectionChanged() function: add code to gather the information required to perform the query, then call the QueryFeatureLayer function (that you will write in a coming step).

    MainWindow.xaml.cs
    Use dark colors for code blocks
                                                                                      
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    using Esri.ArcGISRuntime.Geometry;
    using Esri.ArcGISRuntime.Mapping;
    
    namespace QueryAFeatureLayerSQL
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
    
            public MainWindow()
            {
                InitializeComponent();
    
                MapPoint mapCenterPoint = new MapPoint(-118.805, 34.027, SpatialReferences.Wgs84);
                MainMapView.SetViewpoint(new Viewpoint(mapCenterPoint, 100000));
            }
    
            private async void QueryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
    
                // Since the first choice in the combo box are instructions for the app
                // (not actual SQL where clause syntax), ignore it.
                if (QueryComboBox.SelectedIndex != 0)
                {
                    // Get the view model using the ID given for the static resource in the XAML.
                    MapViewModel currentMapViewModel = this.FindResource("MapViewModel") as MapViewModel;
    
                    // Get the current view point extent.
                    Envelope currentExtent = MainMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry as Envelope;
    
                    // Define the string ID for the feature layer to query.
                    string featureLayerId = "Parcels";
    
                    // Define the SQL query where clause to apply to the feature layer.
                    // Several SQL query strings were pre-populated in the combo box.
                    // This line of code gets the selected choice from the combo box
                    // and assigns it to the SQL query string.
                    string sqlQuery = QueryComboBox.SelectedValue.ToString();
    
                    // Call the function in the view model that queries a feature layer. Pass in the:
                    // (1) feature layer ID
                    // (2) specific SQL syntax for the feature layer
                    // (3) current map extent
                    await currentMapViewModel.QueryFeatureLayer(featureLayerId, sqlQuery, currentExtent);
                }
    
            }
    
        }
    
    }
    

Add the parcels layer to the map and set selection properties

You now need to begin working in a different code file within this project.

First, add the LA parcels FeatureLayer to the map's collection of data layers (GeoModel.OperationalLayers). Providing the Layer.Id allows for referencing the parcels layer from the layer collection when needed. Define the selection color via the map view's SelectionProperties to distinguish selected features in the map.

  1. In the Visual Studio > Solution Explorer, double-click MapViewModel.cs to open the file.

    The project uses the Model-View-ViewModel (MVVM) design pattern to separate the application logic (view model) from the user interface (view). MapViewModel.cs contains the view model class for the application, called MapViewModel. See the Microsoft documentation for more information about the Model-View-ViewModel pattern.

  2. Add additional required using statements at the top of the class. These make your code more concise and allow you to use classes from these namespaces without having to fully qualify them.

    MapViewModel.cs
    Use dark colors for code blocks
                                                                                                                       
    Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Esri.ArcGISRuntime.Geometry;
    using Esri.ArcGISRuntime.Mapping;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    using Esri.ArcGISRuntime.Data;
    using Esri.ArcGISRuntime.UI;
    using System.Threading.Tasks;
    
    namespace QueryAFeatureLayerSQL
    {
    
        class MapViewModel : INotifyPropertyChanged
        {
    
            public MapViewModel()
            {
                SetupMap();
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private Map _map;
            public Map Map
            {
                get { return _map; }
                set
                {
                    _map = value;
                    OnPropertyChanged();
                }
            }
    
            private SelectionProperties _selectionProps;
            public SelectionProperties SelectionProps {
                get { return _selectionProps; }
                set
                {
                    _selectionProps = value;
                    OnPropertyChanged();
                }
            }
    
            private void SetupMap()
            {
                // Create a new map with a 'topographic vector' basemap.
                Map = new Map(BasemapStyle.ArcGISTopographic);
    
                // Add a layer that shows parcels for Los Angeles County.
                Uri parcelsUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0");
                FeatureLayer parcelsFeatureLayer = new FeatureLayer(parcelsUri);
    
                // Give the layer an ID so we can easily find it later, then add it to the map.
                parcelsFeatureLayer.Id = "Parcels";
                Map.OperationalLayers.Add(parcelsFeatureLayer);
    
                // Create selection properties (bound to the MapView).
                SelectionProperties selectionProps = new SelectionProperties();
                selectionProps.Color = System.Drawing.Color.Yellow;
                this.SelectionProps = selectionProps;
    
            }
    
            public async Task QueryFeatureLayer(string layerId, string whereExpression, Envelope queryExtent)
            {
                // Get the layer based on its Id.
                FeatureLayer featureLayerToQuery = _map.OperationalLayers[layerId] as FeatureLayer;
    
                // Get the feature table from the feature layer.
                FeatureTable featureTableToQuery = featureLayerToQuery.FeatureTable;
    
                // Clear any existing selection.
                featureLayerToQuery.ClearSelection();
    
                // Create the query parameters using the where expression and extent passed in.
                QueryParameters queryParams = new QueryParameters
                {
                    Geometry = queryExtent,
                    ReturnGeometry = true,
                    WhereClause = whereExpression,
                };
    
                // Query the table and get the list of features in the result.
                FeatureQueryResult queryResult = await featureTableToQuery.QueryFeaturesAsync(queryParams);
    
                // Loop over each feature from the query result.
                foreach (Feature feature in queryResult)
                {
                    // Select each feature.
                    featureLayerToQuery.SelectFeature(feature);
                }
            }
    
        }
    }
    
  3. Just after the section of code that defines the Map public property, create a similar SelectionProps public property as follows.

    MapViewModel.cs
    Use dark colors for code blocks
                                                                                                                       
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Esri.ArcGISRuntime.Geometry;
    using Esri.ArcGISRuntime.Mapping;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    using Esri.ArcGISRuntime.Data;
    using Esri.ArcGISRuntime.UI;
    using System.Threading.Tasks;
    
    namespace QueryAFeatureLayerSQL
    {
    
        class MapViewModel : INotifyPropertyChanged
        {
    
            public MapViewModel()
            {
                SetupMap();
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private Map _map;
            public Map Map
            {
                get { return _map; }
                set
                {
                    _map = value;
                    OnPropertyChanged();
                }
            }
    
            private SelectionProperties _selectionProps;
            public SelectionProperties SelectionProps {
                get { return _selectionProps; }
                set
                {
                    _selectionProps = value;
                    OnPropertyChanged();
                }
            }
    
            private void SetupMap()
            {
                // Create a new map with a 'topographic vector' basemap.
                Map = new Map(BasemapStyle.ArcGISTopographic);
    
                // Add a layer that shows parcels for Los Angeles County.
                Uri parcelsUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0");
                FeatureLayer parcelsFeatureLayer = new FeatureLayer(parcelsUri);
    
                // Give the layer an ID so we can easily find it later, then add it to the map.
                parcelsFeatureLayer.Id = "Parcels";
                Map.OperationalLayers.Add(parcelsFeatureLayer);
    
                // Create selection properties (bound to the MapView).
                SelectionProperties selectionProps = new SelectionProperties();
                selectionProps.Color = System.Drawing.Color.Yellow;
                this.SelectionProps = selectionProps;
    
            }
    
            public async Task QueryFeatureLayer(string layerId, string whereExpression, Envelope queryExtent)
            {
                // Get the layer based on its Id.
                FeatureLayer featureLayerToQuery = _map.OperationalLayers[layerId] as FeatureLayer;
    
                // Get the feature table from the feature layer.
                FeatureTable featureTableToQuery = featureLayerToQuery.FeatureTable;
    
                // Clear any existing selection.
                featureLayerToQuery.ClearSelection();
    
                // Create the query parameters using the where expression and extent passed in.
                QueryParameters queryParams = new QueryParameters
                {
                    Geometry = queryExtent,
                    ReturnGeometry = true,
                    WhereClause = whereExpression,
                };
    
                // Query the table and get the list of features in the result.
                FeatureQueryResult queryResult = await featureTableToQuery.QueryFeaturesAsync(queryParams);
    
                // Loop over each feature from the query result.
                foreach (Feature feature in queryResult)
                {
                    // Select each feature.
                    featureLayerToQuery.SelectFeature(feature);
                }
            }
    
        }
    }
    
  4. Add code to the SetupMap() function that adds the parcels feature layer to the map and sets the selection properties.

    MapViewModel.cs
    Use dark colors for code blocks
                                                                                                                       
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Esri.ArcGISRuntime.Geometry;
    using Esri.ArcGISRuntime.Mapping;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    using Esri.ArcGISRuntime.Data;
    using Esri.ArcGISRuntime.UI;
    using System.Threading.Tasks;
    
    namespace QueryAFeatureLayerSQL
    {
    
        class MapViewModel : INotifyPropertyChanged
        {
    
            public MapViewModel()
            {
                SetupMap();
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private Map _map;
            public Map Map
            {
                get { return _map; }
                set
                {
                    _map = value;
                    OnPropertyChanged();
                }
            }
    
            private SelectionProperties _selectionProps;
            public SelectionProperties SelectionProps {
                get { return _selectionProps; }
                set
                {
                    _selectionProps = value;
                    OnPropertyChanged();
                }
            }
    
            private void SetupMap()
            {
                // Create a new map with a 'topographic vector' basemap.
                Map = new Map(BasemapStyle.ArcGISTopographic);
    
                // Add a layer that shows parcels for Los Angeles County.
                Uri parcelsUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0");
                FeatureLayer parcelsFeatureLayer = new FeatureLayer(parcelsUri);
    
                // Give the layer an ID so we can easily find it later, then add it to the map.
                parcelsFeatureLayer.Id = "Parcels";
                Map.OperationalLayers.Add(parcelsFeatureLayer);
    
                // Create selection properties (bound to the MapView).
                SelectionProperties selectionProps = new SelectionProperties();
                selectionProps.Color = System.Drawing.Color.Yellow;
                this.SelectionProps = selectionProps;
    
            }
    
            public async Task QueryFeatureLayer(string layerId, string whereExpression, Envelope queryExtent)
            {
                // Get the layer based on its Id.
                FeatureLayer featureLayerToQuery = _map.OperationalLayers[layerId] as FeatureLayer;
    
                // Get the feature table from the feature layer.
                FeatureTable featureTableToQuery = featureLayerToQuery.FeatureTable;
    
                // Clear any existing selection.
                featureLayerToQuery.ClearSelection();
    
                // Create the query parameters using the where expression and extent passed in.
                QueryParameters queryParams = new QueryParameters
                {
                    Geometry = queryExtent,
                    ReturnGeometry = true,
                    WhereClause = whereExpression,
                };
    
                // Query the table and get the list of features in the result.
                FeatureQueryResult queryResult = await featureTableToQuery.QueryFeaturesAsync(queryParams);
    
                // Loop over each feature from the query result.
                foreach (Feature feature in queryResult)
                {
                    // Select each feature.
                    featureLayerToQuery.SelectFeature(feature);
                }
            }
    
        }
    }
    

Create a function to query the parcels layer and select the result

In this step, create a new function that queries a FeatureLayer (identified using its ID) using both attribute and spatial criteria. After clearing any currently selected features, a new query will be executed to find features in the map's current extent that meet the selected attribute expression. The features in the FeatureQueryResult will be selected in the parcels layer.

  1. Add the following new method named QueryFeatureLayer() just after the SetupMap() method.

    MapViewModel.cs
    Use dark colors for code blocks
                                                                                                                       
    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    //   Copyright 2022 Esri
    //   Licensed under the Apache License, Version 2.0 (the "License");
    //   you may not use this file except in compliance with the License.
    //   You may obtain a copy of the License at
    //
    //   https://www.apache.org/licenses/LICENSE-2.0
    //
    //   Unless required by applicable law or agreed to in writing, software
    //   distributed under the License is distributed on an "AS IS" BASIS,
    //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    //   See the License for the specific language governing permissions and
    //   limitations under the License.
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Esri.ArcGISRuntime.Geometry;
    using Esri.ArcGISRuntime.Mapping;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    using Esri.ArcGISRuntime.Data;
    using Esri.ArcGISRuntime.UI;
    using System.Threading.Tasks;
    
    namespace QueryAFeatureLayerSQL
    {
    
        class MapViewModel : INotifyPropertyChanged
        {
    
            public MapViewModel()
            {
                SetupMap();
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private Map _map;
            public Map Map
            {
                get { return _map; }
                set
                {
                    _map = value;
                    OnPropertyChanged();
                }
            }
    
            private SelectionProperties _selectionProps;
            public SelectionProperties SelectionProps {
                get { return _selectionProps; }
                set
                {
                    _selectionProps = value;
                    OnPropertyChanged();
                }
            }
    
            private void SetupMap()
            {
                // Create a new map with a 'topographic vector' basemap.
                Map = new Map(BasemapStyle.ArcGISTopographic);
    
                // Add a layer that shows parcels for Los Angeles County.
                Uri parcelsUri = new Uri("https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0");
                FeatureLayer parcelsFeatureLayer = new FeatureLayer(parcelsUri);
    
                // Give the layer an ID so we can easily find it later, then add it to the map.
                parcelsFeatureLayer.Id = "Parcels";
                Map.OperationalLayers.Add(parcelsFeatureLayer);
    
                // Create selection properties (bound to the MapView).
                SelectionProperties selectionProps = new SelectionProperties();
                selectionProps.Color = System.Drawing.Color.Yellow;
                this.SelectionProps = selectionProps;
    
            }
    
            public async Task QueryFeatureLayer(string layerId, string whereExpression, Envelope queryExtent)
            {
                // Get the layer based on its Id.
                FeatureLayer featureLayerToQuery = _map.OperationalLayers[layerId] as FeatureLayer;
    
                // Get the feature table from the feature layer.
                FeatureTable featureTableToQuery = featureLayerToQuery.FeatureTable;
    
                // Clear any existing selection.
                featureLayerToQuery.ClearSelection();
    
                // Create the query parameters using the where expression and extent passed in.
                QueryParameters queryParams = new QueryParameters
                {
                    Geometry = queryExtent,
                    ReturnGeometry = true,
                    WhereClause = whereExpression,
                };
    
                // Query the table and get the list of features in the result.
                FeatureQueryResult queryResult = await featureTableToQuery.QueryFeaturesAsync(queryParams);
    
                // Loop over each feature from the query result.
                foreach (Feature feature in queryResult)
                {
                    // Select each feature.
                    featureLayerToQuery.SelectFeature(feature);
                }
            }
    
        }
    }
    
  2. Click Debug > Start Debugging (or press <F5> on the keyboard) to run the app.

The app loads with the map centered on the Santa Monica Mountains in California with the parcels feature layer displayed. Choose an attribute expression, and parcels in the current extent that meet the selected criteria will display in the specified selection color.

What's next?

Learn how to use additional API features, ArcGIS loction services, and ArcGIS tools in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.