Select to view content in your preferred language

Please help with ExecuteRelationshipQueryAsync

4633
19
10-07-2010 03:37 PM
RickHendrickson
Occasional Contributor
I can't figure out how to get the results from the related table. Using the query task I can get all the graphics and fields I want by basically using the the spatial query sample found here: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SpatialQuery

What is the proper way to get the related table information through the spatial query? For the 'regular query' I think you pass in the geometry from the draw surface. How does the relationshipquery work?

I'm desperate, Thanks!

Rick
0 Kudos
19 Replies
JenniferNery
Esri Regular Contributor
In the code-snippet below,
incidentsLayer is the FeatureLayer displayed on my map http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0;
graphic is a feature in my incidentsLayer;
"agree_with_incident" is a field in the related table http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/1;
voteCount is the value I need to update based on the result of my query.

        private void QueryRelatedTable()
        {
            int objectId = Convert.ToInt32(graphic.Attributes[incidentsLayer.LayerInfo.ObjectIdField]);
            int relationshipId = -1;
            foreach (var relationship in incidentsLayer.LayerInfo.Relationships)
            {
                relationshipId = relationship.RelatedTableId;
                break;
            }
            QueryTask qt = new QueryTask(incidentsLayer.Url);
   qt.DisableClientCaching = true;
            RelationshipParameter rp = new RelationshipParameter();
            rp.ObjectIds = new int[]{objectId};
            rp.OutFields = new string[]{"agree_with_incident"};
            rp.RelationshipId = relationshipId;         
            qt.ExecuteRelationshipQueryCompleted += qt_ExecuteRelationshipQueryCompleted;            
            qt.ExecuteRelationshipQueryAsync(rp);
        }

        private void qt_ExecuteRelationshipQueryCompleted(object sender, RelationshipEventArgs e)
        {
            RelationshipResult pr = e.Result;
            voteCount = 0;
            foreach (var item in pr.RelatedRecordsGroup)
            {
                voteCount = item.Value.Count();
                break;
            }              
        }

0 Kudos
RickHendrickson
Occasional Contributor
Thanks Jennifer. I am giving this a shot now. I'll let you know how it goes.
Rick
0 Kudos
RickHendrickson
Occasional Contributor
I think I am close but not quite there. Can you please take a look at my code here and give me some advice?

How I want this to work is for the user to select a line on the map and then view a list of drawings associated with the line. It is a one to many relationship thus the reason for the related table. So I have it setup right now so I can select a line and view the data in the primary table. This first bit of code is the handler for the query:

Private Sub QueryTaskab_ExecuteCompleted(ByVal sender As Object, ByVal args As ESRI.ArcGIS.Client.Tasks.QueryEventArgs)
        Dim featureSet As FeatureSet = args.FeatureSet

        If featureSet Is Nothing OrElse featureSet.Features.Count < 1 Then
            MessageBox.Show("No features retured from query")
            Return
        End If

        Dim graphicsLayer As GraphicsLayer = TryCast(MyMap.Layers("MySelectionGraphicsLayer"), GraphicsLayer)

        If featureSet IsNot Nothing AndAlso featureSet.Features.Count > 0 Then
            For Each feature As Graphic In featureSet.Features
                feature.Symbol = TryCast(LayoutRoot.Resources("ResultsFillSymbol"), Symbol)
                graphicsLayer.Graphics.Insert(0, feature)
            Next feature
            ResultsDisplay.Visibility = Visibility.Visible
        End If
        MyDrawSurface.IsEnabled = False



        Dim objectid As Integer = Convert.ToInt32(featureSet.ObjectIdFieldName)
               Dim queryTaskab As New QueryTask("http://...../ArcGIS/rest/services/10106734/_AsBuiltRelate10/MapServer/0")

        AddHandler queryTaskab.Failed, AddressOf QueryTaskab_Failed

        AddHandler queryTaskab.ExecuteRelationshipQueryCompleted, AddressOf QueryTaskab_ExecuteRelationshipQueryCompleted

        Dim rquery As RelationshipParameter = New ESRI.ArcGIS.Client.Tasks.RelationshipParameter()
        rquery.ObjectIds = New Integer() {objectid}

        Dim outList As New List(Of String)
        outList.Add("OBJECTID")
        outList.Add("REDBOOKNUM")
        rquery.RelationshipId = 0
        rquery.OutFields = outList
        queryTaskab.ExecuteRelationshipQueryAsync(rquery)
    End Sub


The second half of that code is where I am setting up the relationship query. Having trouble passing in the objectids I think.

Thanks
Rick
0 Kudos
DeraldDudley
Deactivated User
Rick,

Did you ever figure this out.  I'm have the same problem passing the objectIDs to the RelationshipParameters object.

Cheers,
Derald
0 Kudos
JenniferNery
Esri Regular Contributor
I think in the code that you posted, you are having problem with this line

Dim objectid As Integer = Convert.ToInt32(featureSet.ObjectIdFieldName)


The ObjectIdField property is the key to the attribute dictionary.
http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.FeatureSer...
What you need to convert to an integer is the attribute value for that key, the actual object id.

In the code I posted earlier, this is the VB version; where incidentLayer is a FeatureLayer:
Dim objectId As Integer = Convert.ToInt32(graphic.Attributes(incidentsLayer.LayerInfo.ObjectIdField)) 


I used a FeatureLayer to get LayerInfo and ObjectIdField. I did not want to hardcode the key used to get the object id. http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.FeatureSer...
You need not do the same thing, you can hardcode the key if you want, but you cannot convert the key to an integer. You need to get the value first and then convert 🙂
0 Kudos
DeraldDudley
Deactivated User
Here was my solution.  Ill try yours next.  Thanks!  😉

Private Sub Query_ExecuteCompleted(ByVal sender As Object, ByVal queryArgs As QueryEventArgs)
    If queryArgs.FeatureSet Is Nothing Then
      Return
    End If

    Dim resultFeatureSet As FeatureSet = queryArgs.FeatureSet

    Dim graphicsLayer As ESRI.ArcGIS.Client.GraphicsLayer = TryCast(Map1.Layers("Institutions"), ESRI.ArcGIS.Client.GraphicsLayer)

    If resultFeatureSet IsNot Nothing AndAlso resultFeatureSet.Features.Count > 0 Then
      For Each graphicFeature As ESRI.ArcGIS.Client.Graphic In resultFeatureSet.Features
        graphicsLayer.Graphics.Add(graphicFeature)

      Next graphicFeature

      Dim expandPercentage As Double = 30

      Dim widthExpand As Double = graphicsLayer.FullExtent.Width * (expandPercentage / 100)
      Dim heightExpand As Double = graphicsLayer.FullExtent.Height * (expandPercentage / 100)

      Dim displayExtent As New  _
      ESRI.ArcGIS.Client.Geometry.Envelope(graphicsLayer.FullExtent.XMin - (widthExpand / 2), _
                                           graphicsLayer.FullExtent.YMin - (heightExpand / 2), _
                                           graphicsLayer.FullExtent.XMax + (widthExpand / 2), _
                                           graphicsLayer.FullExtent.YMax + (heightExpand / 2))
      Map1.ZoomTo(displayExtent)
    End If

    RelatedQuery(resultFeatureSet)

  End Sub

  Private Sub RelatedQuery(ByVal resultsFS As FeatureSet)

    Dim qtRelatedTables As New QueryTask("http://204.68.195.113/ArcGIS/rest/services/DOTResearch/DOTResearchGDB/MapServer/4")
    AddHandler qtRelatedTables.Failed, AddressOf qtRelatedTables_Failed
    AddHandler qtRelatedTables.ExecuteRelationshipQueryCompleted, AddressOf qtRelatedTables_ExecuteRelationshipQueryCompleted

    Dim listObjIds As New List(Of Integer)
    Dim intIndex As Integer = 0
    For Each Feat In resultsFS.Features
      listObjIds.Add(resultsFS.Features(intIndex).Attributes("OBJECTID"))
      intIndex = intIndex + 1
    Next

    Dim rp As New RelationshipParameter
    rp.ObjectIds = listObjIds
    rp.RelationshipId = 0
    rp.ReturnGeometry = False
    rp.OutFields = {"*"}

    qtRelatedTables.ExecuteRelationshipQueryAsync(rp)

  End Sub
  Private Sub qtRelatedTables_ExecuteRelationshipQueryCompleted(ByVal sender As Object, ByVal e As RelationshipEventArgs)
    If e.Result Is Nothing Then
      Return
    Else
      MessageBox.Show("Bingo")
    End If
  End Sub
  Private Sub qtRelatedTables_Failed(ByVal sender As Object, ByVal args As TaskFailedEventArgs)
    MessageBox.Show("Query failed: " & args.Error.Message)
  End Sub

  Private Sub Query_Failed(ByVal sender As Object, ByVal args As TaskFailedEventArgs)
    MessageBox.Show("Query failed: " & args.Error.Message)
  End Sub
0 Kudos
JenniferNery
Esri Regular Contributor
Your code looks good. I think you are in the right track now. It works, right?
0 Kudos
DeraldDudley
Deactivated User
Jenn,

I got yours to work using the code below.  It is retrieves the Realted records per individual feature.  I was confused because I thought the RelationshipParameter.ObjectIDs was looking for a list of IDs.  I was trying to set RelationshipParameter.ObjectIDs = FeatureSet.ObjectIDs but I think there is a conversion issue.

Many Thanks,
Derald


If queryArgs.FeatureSet Is Nothing Then
      Return
    End If

    Dim FeatLayr As ESRI.ArcGIS.Client.FeatureLayer = Map1.Layers("Institutions")
    Dim resultFeatureSet As FeatureSet = queryArgs.FeatureSet
    Dim graphicsLayer As ESRI.ArcGIS.Client.GraphicsLayer = TryCast(Map1.Layers("Institutions"), ESRI.ArcGIS.Client.GraphicsLayer)

For Each graphicFeature As ESRI.ArcGIS.Client.Graphic In resultFeatureSet.Features
  graphicsLayer.Graphics.Add(graphicFeature)
  RelatedQuery(Convert.ToInt32(graphicFeature.Attributes(FeatLayr.LayerInfo.ObjectIdField)))
Next graphicFeature

Private Sub RelatedQuery(ByVal ObjectId As Int32)

Dim qtRelatedTables As New QueryTask("http://204.68.195.113/ArcGIS/rest/services/DOTResearch/DOTResearchGDB/MapServer/4")

AddHandler qtRelatedTables.Failed, AddressOf qtRelatedTables_Failed
AddHandler qtRelatedTables.ExecuteRelationshipQueryCompleted, AddressOf qtRelatedTables_ExecuteRelationshipQueryCompleted

    Dim rp As New RelationshipParameter
    rp.ObjectIds = {ObjectId}
    'rp.ObjectIds = resultsFS.ObjectIDs
    rp.RelationshipId = 0
    rp.ReturnGeometry = False
    rp.OutFields = {"*"}

    qtRelatedTables.ExecuteRelationshipQueryAsync(rp)

  End Sub
0 Kudos
DaveTimmins
Deactivated User
Hi Jennifer,

I think there's a bug / feature 🙂 in the way that the object id field name is used. If you look at the service metadata for

http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/MapServer/0

or

http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer/0

you can see that the objectid field reported for the service is objectid.
If you look at the fields data for the service, the objectid field also has an alias set to Object ID and this is the value that is in the Attributes so it can't find the values correctly. So basically it isn't using the alias when it looks like it should be.

Cheers,
0 Kudos