Offline Use - Related Table query

5110
5
Jump to solution
12-22-2014 07:21 AM
ColinCole
New Contributor II

Hello,

Per the Esri Preparing Data for Offline Use (Enabling Sync on ArcGIS Server Feature Services) documentation, it states:

"Relationship Classes and Attachments MUST use GlobalID as the Primary Key"

However, when attempting to use AGSRelationshipQuery to query the related table, the parameters only allow the use of ObjectIds (via the NSArray objectIds property).

Can anyone provide clarification on this? Or an alternative method to querying related tables during offline use?

Thanks,

Colin

0 Kudos
1 Solution

Accepted Solutions
MichaelDavis3
Occasional Contributor III

Here's a snippit of our code to query all the contents of a non-spatial table:

-(void) loadSites

{

    NSError* error;

    _gdb = [AGSGDBGeodatabase geodatabaseWithName:@"msm" error:&error];

    self.environmentFeatureTable = [_gdb featureTableForLayerName:@"SurveyEnvironment"];

   

    NSArray *fields = [[NSArray alloc] initWithObjects:@"DateTime", @"EffortStatus", @"DateTime", @"EnvironmentID", nil];

   

    AGSQuery *query = [[AGSQuery alloc] init];

    query.orderByFields = @[@"DateTime DESC"];

    query.whereClause = @"1=1";

    //query.outFields = @[@"*"];

    query.outFields = fields;

    query.returnGeometry = NO;

   

    [self.environmentFeatureTable queryResultsWithParameters:query completion:^(NSArray *results, NSError *error) {

        self.environmentQueryResults = results;

        [self.tableView reloadData];

    }];

}

If we are trying to access related records we would pass in the key when we fire up this view and set it as an item in the whereClause.

View solution in original post

5 Replies
MichaelDavis3
Occasional Contributor III

We went down that road when we first implemented offline related features and ran into some issues.  For us it has been more reliable to abandon ESRI's relationships entirely and maintain our own using machine generated keys.  When doing this it is relatively easy to pass the key in and run a query against the table.

ColinCole
New Contributor II

Thanks Michael. What method did you use to run the query against the table?

0 Kudos
MichaelDavis3
Occasional Contributor III

We just use an AGSQuery object and execute it against the "feature table".  I put that in quotes because it doesn't have to be a feature layer - a non-spatial table works just fine... as long as we set the returnGeometry flag to NO.

0 Kudos
MichaelDavis3
Occasional Contributor III

Here's a snippit of our code to query all the contents of a non-spatial table:

-(void) loadSites

{

    NSError* error;

    _gdb = [AGSGDBGeodatabase geodatabaseWithName:@"msm" error:&error];

    self.environmentFeatureTable = [_gdb featureTableForLayerName:@"SurveyEnvironment"];

   

    NSArray *fields = [[NSArray alloc] initWithObjects:@"DateTime", @"EffortStatus", @"DateTime", @"EnvironmentID", nil];

   

    AGSQuery *query = [[AGSQuery alloc] init];

    query.orderByFields = @[@"DateTime DESC"];

    query.whereClause = @"1=1";

    //query.outFields = @[@"*"];

    query.outFields = fields;

    query.returnGeometry = NO;

   

    [self.environmentFeatureTable queryResultsWithParameters:query completion:^(NSArray *results, NSError *error) {

        self.environmentQueryResults = results;

        [self.tableView reloadData];

    }];

}

If we are trying to access related records we would pass in the key when we fire up this view and set it as an item in the whereClause.

ColinCole
New Contributor II

Ahhh ok, I kept getting 0 results when using that method. I just figured out why.

The problem was in my geodatabase initialization. In order to properly fetch non-spatial records, you have to set the queries property in the parameters of the initialization method (see below).

AGSGDBGenerateParameters *params = [[AGSGDBGenerateParameters alloc]initWithFeatureServiceInfo:self.gdbTask.featureServiceInfo];

    params.extent = self.mapView.maxEnvelope;

    params.outSpatialReference = self.mapView.spatialReference;

    NSMutableArray* layers = [[NSMutableArray alloc]init];

   

    // Add Layer IDs

    [layers addObject:[NSNumber numberWithInt: 0]];

    [layers addObject:[NSNumber numberWithInt: 1]];

    params.layerIDs = layers;

   

    // Set AGSGDBLayerQuery for the non-spatial records

    AGSGDBLayerQuery *gdbQuery = [[AGSGDBLayerQuery alloc]init];

    NSMutableArray *gdbQueries = [[NSMutableArray alloc]init];

    gdbQuery.useGeometry = NO;

    gdbQuery.layerID = 1;

    gdbQuery.whereClause = @"1=1";

    gdbQuery.option = AGSGDBQueryOptionAll;

    [gdbQueries addObject:gdbQuery];

    params.queries = gdbQueries;

   

    self.newlyDownloaded = NO;

    [self.gdbTask generateGeodatabaseWithParameters:params downloadFolderPath:nil useExisting:NO status:^(AGSResumableTaskJobStatus status, NSDictionary *userInfo) {

Thanks again Michael