---
title: Provider location retrieval
summary: Retrieves a single provider location by ID, or a filtered collection of provider locations by owning provider or provider type code, and exposes each location's addresses, relationships, ineligibility periods, and ancillary data as lazily loaded children.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.View.Provider
reference_type: package
operation_id: OP-VP-02
trigger: Caller calls clsProviderLocation.GetProviderLocation(dpi, providerLocationID), or clsProviderLocationCollection.GetProviderLocations(dpi, providerID) / GetProviderLocations(dpi, providerTypeCode)
---

# Provider location retrieval

Provider location retrieval reads the `PROVIDER_LOCATION` table, either as a single location by its identifier or as a collection filtered by owning provider ID or by provider type code. `clsProviderLocation` is the richest entity in this library: beyond its own header fields, it lazily resolves its owning provider, its addresses, its parent/child relationships, its ineligibility periods, its provider-type reference data, and four ancillary location-scoped lists (MCO enrollments, DCBS cost charges, services, and service contracts).

| Field | Value |
| --- | --- |
| **Operation ID** | OP-VP-02 |
| **Trigger** | `clsProviderLocation.GetProviderLocation(inDataportal, inProviderLocationID)`; `clsProviderLocationCollection.GetProviderLocations(inDataportal, providerID)`; `clsProviderLocationCollection.GetProviderLocations(inDataportal, providerTypeCode)` |
| **Inputs** | Provider location ID (Decimal); or provider ID (Decimal); or provider type code (String) |
| **Outputs** | A populated `clsProviderLocation` or `clsProviderLocationCollection`; lazily resolved `Provider`, `Addresses`/`ActiveAddresses`, `ChildRelationships`/`ParentRelationships`, `IneligibilityPeriods`, `ProviderType`, `DCBSCostCharges`, `MCOList`, `Services`, `ServiceContracts` |
| **Primary components** | `clsProviderLocation.Fill`, `clsProviderLocation.Load`, `clsProviderLocationCollection.GetProviderLocations`, `clsProviderLocationCollection.Criteria`, `clsProviderLocationCollection.FilterBy_ProviderTypeCode`, `clsProviderLocationCollection.FilterBy_ProviderTypeCodeAndEffectiveDate` |
| **Entry point** | `Business\SAIF.Business.View.Provider\clsProviderLocation.vb` |

## Steps

1. **Select the collection filter.** `GetProviderLocations` is overloaded: passing a Decimal provider ID selects `ProviderLocationFilterTypes.ByProviderID`; passing a String provider type code selects `ProviderLocationFilterTypes.ByProviderTypeCode`. The criteria retains whichever filter was supplied.
2. **Bind the filter parameter.** `BeforeRetrieve` binds `:ProviderID` or `:ProviderTypeCode` depending on the selected filter type and caches the bound value on the collection instance.
3. **Compose the filtered retrieve SQL.** The collection criteria's `RetrieveSQL` starts from `clsProviderLocation.Criteria.RETRIEVE_SELECT_SQL` and appends `WHERE PROVIDER_SEQ_NUM = :ProviderID` or `WHERE PROVIDER_TYPE_CODE = :ProviderTypeCode` depending on the filter ([SQL-011](../sql/SQL-011-saif-business-view-provider.md), [SQL-012](../sql/SQL-012-saif-business-view-provider.md), [PROVIDER_LOCATION](../database-tables.md#provider_location)).
4. **Populate the collection.** `AfterRetrieve` iterates the result set, constructs a `clsProviderLocation` per row, calls `Load` (fills the row and marks it old), and adds each to the collection.
5. **Retrieve a single location.** The single-location retrieval path binds `:ProviderLocationID` and executes the location's own retrieve SQL against `PROVIDER_LOCATION` ([SQL-010](../sql/SQL-010-saif-business-view-provider.md), [PROVIDER_LOCATION](../database-tables.md#provider_location)); `AfterRetrieve` reads at most one row, fills it, and marks it old only when a row was found.
6. **Resolve the owning provider on demand.** Reading `Provider` on a populated location lazily retrieves the parent `clsProvider` by the location's provider ID and caches it.

   > **Origin**: This lazy load delegates to the [Provider retrieval](provider-retrieval.md) operation implemented in this library.
7. **Resolve addresses on demand.** Reading `Addresses` lazily retrieves the location's address collection; `ActiveAddresses` (with or without a supplied date) filters that collection down to addresses whose effective window covers the target date.

   > **Origin**: This lazy load delegates to the [Provider address retrieval](provider-address-retrieval.md) operation implemented in this library.
8. **Resolve relationships on demand.** Reading `ChildRelationships` or `ParentRelationships` lazily retrieves the corresponding relationship collection for the location.

   > **Origin**: This lazy load delegates to the [Provider relationship retrieval](provider-relationship-retrieval.md) operation implemented in this library.
9. **Resolve ineligibility periods on demand.** Reading `IneligibilityPeriods` retrieves the location's ineligibility-period collection every time it is accessed — this property is not cached, unlike the other lazy-load properties on this class.* `IsDuringIneligibilityPeriod(effectiveDate)` re-retrieves that collection and tests whether any period's window covers the supplied date.

   > **Origin**: This lazy load delegates to the [Provider ineligibility period retrieval](provider-ineligibility-period-retrieval.md) operation implemented in this library.
10. **Resolve provider-type reference data on demand.** Reading `ProviderType` lazily retrieves and caches the provider type record matching the location's provider type code.

    > **Origin**: This lazy load delegates to the [Provider type reference data](provider-type-reference-data.md) operation implemented in this library.
11. **Resolve ancillary location data on demand.** Reading `DCBSCostCharges`, `MCOList`, `Services`, or `ServiceContracts` lazily constructs and caches the corresponding list type, scoped to this location's ID.

    > **Origin**: This lazy load delegates to the [Provider location ancillary data retrieval](provider-location-ancillary-data.md) operation implemented in this library.
12. **Filter a location collection by provider type and eligibility.** `FilterBy_ProviderTypeCode` (defaulting to today) and `FilterBy_ProviderTypeCodeAndEffectiveDate` (explicit date) return the subset of an already-retrieved collection whose provider type code matches and whose `IsDuringIneligibilityPeriod` check for the given date is false — a purely in-memory filter over previously loaded locations, not a new database query beyond the per-location ineligibility check in step 9.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([GetProviderLocation or GetProviderLocations called]) --> Which{Single or collection?}
	Which -->|Single, by location ID| Single[Bind ProviderLocationID parameter]
	Which -->|Collection, by provider ID| ByProv[Bind ProviderID parameter]
	Which -->|Collection, by type code| ByType[Bind ProviderTypeCode parameter]
	Single --> Exec1[Execute retrieve query]
	Exec1 --> Row{Row found?}
	Row -->|Yes| Fill1[Fill location; MarkOld]
	Row -->|No| Empty1([Object left in default state])
	ByProv --> Exec2[Execute retrieve query]
	ByType --> Exec2
	Exec2 --> Loop[For each row: create clsProviderLocation,<br>Load, add to collection]
	Loop --> Done2([Populated collection returned])
	Fill1 --> Use{Consumer reads child property}
	Use -->|Provider| P[Lazy load owning provider]
	Use -->|Addresses| A[Lazy load address collection]
	Use -->|Relationships| R[Lazy load relationship collection]
	Use -->|IneligibilityPeriods| I[Re-retrieve every access]
	Use -->|ProviderType| T[Lazy load and cache type]
	Use -->|Ancillary lists| L[Lazy load and cache MCO,<br>DCBS, services, contracts]
```

## Failure and edge-case behavior

- A single-location lookup that matches no row leaves the object in its default (empty) state with no exception raised, consistent with the other retrieval operations in this library.
- `IneligibilityPeriods` re-queries the database on every read rather than caching the result, unlike the other lazy-load properties on this class; repeated calls (for example inside a loop calling `IsDuringIneligibilityPeriod`) each issue a fresh query.*
- `FilterBy_ProviderTypeCodeAndEffectiveDate` calls `IsDuringIneligibilityPeriod` per location in the filtered set, so filtering a large collection by eligibility can issue one ineligibility-period query per location rather than a single batched query.*
- `PrimaryLocation` on the owning `clsProvider` falls back to the first location in the collection when no location is flagged primary, so a provider with locations but none marked primary still returns a location rather than `Nothing`.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources

- `Business\SAIF.Business.View.Provider\clsProviderLocation.vb`
- `Business\SAIF.Business.View.Provider\clsProviderLocationCollection.vb`
