Alternate keys
Alternate keys allow you to define unique identifiers alternative to the primary key of an entity. They are particularly useful in data import scenarios and communication with external partners.
Definition
An alternate key is a set of properties that, when combined, uniquely identify a record in a database table. It can be composed of one or more entity properties.
Main characteristics
- Guaranteed uniqueness: An alternate key automatically generates a unique index on the associated database table
- Search methods: Search methods are generated in repositories to facilitate data access
- Usage in entity views: An alternate key can serve as the key for an entity view
- Import scenarios: They are designed to simplify import processes and exchanges with external systems
Declaring an alternate key
Alternate keys are defined in the module's metadata/EntityAlternateKeys folder. Each alternate key has a name and specifies which properties compose it.
An alternate key can be:
- Simple: Composed of a single property (e.g.,
ExternalID,Code) - Composite: Composed of multiple properties (e.g.,
CategoryID+Code)
Composite alternate keys can combine both scalar properties and foreign keys.
Database impact
Each alternate key generates a unique index on the associated table when you trigger metadata generation from the entity. This ensures data integrity and improves search performance.
To create the unique index, click the "Generate metadata" button from the entity in Neos Studio.
Generated methods in repositories
For each defined alternate key, the Neos generator automatically creates search methods in the entity's repository.
Example with IAKProductRepository
Generated file: TechnicalDemos.Domain/Persistence/IAKProductRepository.cs
public interface IAKProductRepository : IRepository<AKProduct>
{
// Methods for primary key
AKProduct Get(int id);
AKProduct? Find(int id);
Task<AKProduct> GetAsync(int id);
Task<AKProduct?> FindAsync(int id);
// Methods for alternate key "ExternalKey"
AKProduct GetByExternalKey(string? externalID);
AKProduct? FindByExternalKey(string? externalID);
Task<AKProduct> GetByExternalKeyAsync(string? externalID, CancellationToken cancellationToken);
Task<AKProduct?> FindByExternalKeyAsync(string? externalID, CancellationToken cancellationToken);
// Methods for alternate key "NaturalKey" (composite)
AKProduct GetByNaturalKey(int categoryID, string code);
AKProduct? FindByNaturalKey(int categoryID, string code);
Task<AKProduct> GetByNaturalKeyAsync(int categoryID, string code, CancellationToken cancellationToken);
Task<AKProduct?> FindByNaturalKeyAsync(int categoryID, string code, CancellationToken cancellationToken);
}
Method behavior
Alternate key search methods follow the standard pattern:
- Get*: Throws an exception if the entity is not found
- Find*: Returns
nullif the entity is not found
Important: These methods search first in the cache of the Unit of Work, then query the database only if the element is not present. This optimizes performance and avoids unnecessary queries.
Complete example: TechnicalDemos Module
The AlternateKeys module in the TechnicalDemos cluster provides complete examples of alternate key usage.
Module structure
The module contains:
- Entities:
AKCustomer,AKProduct,AKProductCategory,AKOrder,AKOrderDetail - Alternate keys:
ExternalKey: Simple key based onExternalIDNaturalKey: Business key (simple or composite depending on the entity)
- Entity views: Examples with alternate key as primary key
- UI views: Demonstration of interface usage
Accessing the examples
To explore the module and its examples:
- See the TechnicalDemos cluster for installation instructions
- Navigate to the "Alternate Keys" menu in the application