Skip to main content

InstanceService.GetRelatedInstances

Reference

PagedData<RelatedInstance> GetRelatedInstances(Guid instanceId, RelatedInstanceQuery relatedInstanceQuery)

Use GetRelatedInstances to retrieve instances that are related to a specific instance through defined relationships. This API supports complex filtering, sorting, and pagination of related instances across multiple relationship types and target types.

Parameters

  • instanceId: The unique identifier of the source instance for which to retrieve related instances.
  • relatedInstanceQuery: Query object containing relationship filters, attribute filters, sorting criteria, and pagination settings.
    • RelationFilters: Array of relationship filters specifying relation type names, target type names, and relationship direction.
    • AttributeFilterExpressions: Optional attribute-based filtering criteria for the related instances.
    • Skip, Take: Pagination parameters for result set.
    • ParentAttributes: Optional array of parent attribute paths to include in the results.
    • GetCountOnly: When true, returns only the total count without actual data items.

Returns

PagedData<RelatedInstance>:

  • Collection of RelatedInstance objects representing related entities for the specified instance.
  • Each RelatedInstance contains attributes and relationship details.
  • Includes pagination metadata (TotalCount, Skip, Take).
  • Returns empty collection if no related instances are found.

Error Handling & Caveats

  • If the source instance does not exist or the user lacks permission, an AccessDeniedException is thrown.
  • If no relation filters are provided, an ArgumentNullException is thrown with localized message "Relation filter required".
  • If any relation filter has empty RelationTypeName, an ArgumentNullException is thrown with message "Relation filters invalid - RelationTypeName required".
  • If any relation filter has empty TypeName, an ArgumentNullException is thrown with message "Relation filters invalid - TypeName required".
  • Performance is optimized through flush mode management and proper database query execution.
  • Parent attributes are only populated if explicitly requested in the query.
  • Always check for null Items collection before iterating - the API may return null if no related instances are found.
  • When using StateFilter, ensure the state names match exactly as configured in the lifecycle.
  • RelationDirection must be correctly specified (From/To) based on the relationship definition in the schema.
  • Always specify appropriate Skip/Take values for large datasets to avoid performance issues.

Usage

try {
var relatedQuery = new RelatedInstanceQuery {
RelationFilters = new[] {
new RelationFilter {
RelationTypeName = "ReviewerToTask",
TypeName = "Reviewer",
RelationDirection = RelationDirection.From
}
},
Attributes = new[] { "Name", "Email", "Status" },
StateFilter = new[] { "Accepted", "InProgress" },
Skip = 0,
Take = int.MaxValue
};

var reviewers = InstanceService.GetRelatedInstances(taskId, relatedQuery);

if (reviewers?.Items != null && reviewers.Items.Any()) {
foreach (var reviewer in reviewers.Items) {
Console.WriteLine($"Reviewer: {reviewer.Name}");
}
}
} catch (ArgumentNullException ex) {
// Handle missing required parameters
} catch (AccessDeniedException ex) {
// Handle permission errors
}
try {
var subscriptionRenewalQuery = new RelatedInstanceQuery {
RelationFilters = new[] {
new RelationFilter {
RelationTypeName = "ServiceToRenewal",
RelationDirection = RelationDirection.To,
TypeName = "ServiceRenewal"
}
},
Attributes = new[] { "StartPeriod", "EndPeriod" },
StateFilter = new[] { "PaymentCompleted", "PaymentInProcess" },
Skip = 0,
Take = int.MaxValue
};

var approvedRenewals = InstanceService.GetRelatedInstances(serviceId, subscriptionRenewalQuery);

if (approvedRenewals?.Items != null) {
foreach (var renewal in approvedRenewals.Items) {
var startPeriod = renewal.Attributes?.FirstOrDefault(a => a.Name == "StartPeriod");
var endPeriod = renewal.Attributes?.FirstOrDefault(a => a.Name == "EndPeriod");

if (startPeriod?.DateValue != null && endPeriod?.DateValue != null) {
// Process renewal period logic
Console.WriteLine($"Renewal period: {startPeriod.DateValue} to {endPeriod.DateValue}");
}
}
}
} catch (Exception ex) {
Console.WriteLine($"Error retrieving service renewals: {ex.Message}");
}

Example: Getting Division from Department

try {
var departmentToDivisionQuery = new RelatedInstanceQuery {
RelationFilters = new[] {
new RelationFilter {
RelationTypeName = "DivisionToDepartment",
RelationDirection = RelationDirection.From,
TypeName = "Division"
}
},
Attributes = new[] { "Dean" }
};

var division = InstanceService.GetRelatedInstances(departmentId, departmentToDivisionQuery).Items?.FirstOrDefault();

if (division?.Attributes != null) {
var dean = division.Attributes.FirstOrDefault(a => a.Name == "Dean");
if (dean?.UserValues != null && dean.UserValues.Any()) {
// Process dean information
Console.WriteLine($"Dean found: {dean.UserValues.First().DisplayName}");
} else {
throw new Exception("Dean for related division doesn't exist");
}
}
} catch (Exception ex) {
Console.WriteLine($"Error retrieving division: {ex.Message}");
}

Troubleshooting

  • If no results are returned, verify that relationships exist and the user has access to related instances.
  • If RelationTypeName validation fails, ensure the relationship type exists and is spelled correctly.
  • If TypeName validation fails, verify the target instance type exists in the system.
  • For performance issues with large result sets, use pagination (Skip/Take) and consider using GetCountOnly for initial queries.
  • If parent attributes are not populated, ensure the ParentAttributes array contains valid attribute paths in the correct format.
  • For access control issues, verify user permissions on both source and target instances.
  • Always check for null Items collection before iterating - use relatedInstances?.Items != null checks.
  • When using StateFilter, ensure state names match exactly (case-sensitive) as defined in lifecycle configuration.
  • If RelationDirection seems incorrect, verify the relationship definition in the schema and use the correct direction (From/To).
  • For batch operations, always use Take = int.MaxValue to ensure all related instances are retrieved.
  • When accessing specific attributes, always check for null values before using them.