diff --git a/Application/EdFi.Ods.Common/Infrastructure/Repositories/GetEntityByKey.cs b/Application/EdFi.Ods.Common/Infrastructure/Repositories/GetEntityByKey.cs index ec8a286f2..ace03300d 100644 --- a/Application/EdFi.Ods.Common/Infrastructure/Repositories/GetEntityByKey.cs +++ b/Application/EdFi.Ods.Common/Infrastructure/Repositories/GetEntityByKey.cs @@ -22,11 +22,16 @@ namespace EdFi.Ods.Common.Infrastructure.Repositories public class GetEntityByKey : GetEntitiesBase, IGetEntityByKey where TEntity : DomainObjectBase, IDateVersionedEntity, IHasIdentifier { + private readonly IContextProvider _dataManagementResourceContextProvider; + public GetEntityByKey( ISessionFactory sessionFactory, IDomainModelProvider domainModelProvider, IContextProvider dataManagementResourceContextProvider) - : base(sessionFactory, domainModelProvider, dataManagementResourceContextProvider) { } + : base(sessionFactory, domainModelProvider, dataManagementResourceContextProvider) + { + _dataManagementResourceContextProvider = dataManagementResourceContextProvider; + } /// /// Gets a single entity by its composite primary key values. @@ -52,22 +57,25 @@ public async Task GetByKeyAsync(TEntity specification, CancellationToke // Go try to get the existing entity var compositeKeyValues = entityWithKeyValues.GetPrimaryKeyValues(); - // Only look up by composite key if "Id" is not considered part of the "DomainSignature" - if (!compositeKeyValues.Contains("Id")) + if (ShouldTryLoadByCompositePrimaryKey()) { - persistedEntity = (await GetAggregateResultsAsync( - GetWhereClause(compositeKeyValues), q => q.SetParameters(compositeKeyValues), cancellationToken)) - .SingleOrDefault(); - } + // Only look up by composite key if "Id" is not considered part of the "DomainSignature" + if (!compositeKeyValues.Contains("Id")) + { + persistedEntity = (await GetAggregateResultsAsync( + GetWhereClause(compositeKeyValues), q => q.SetParameters(compositeKeyValues), cancellationToken)) + .SingleOrDefault(); + } - if (persistedEntity != null) - { - return persistedEntity; + if (persistedEntity != null) + { + return persistedEntity; + } } - // Does entity have an alternate key? var entityWithAlternateKeyValues = specification as IHasAlternateKeyValues; + // If entity doesn't have an alternate key, we're done. if (entityWithAlternateKeyValues == null) { return null; @@ -84,6 +92,31 @@ public async Task GetByKeyAsync(TEntity specification, CancellationToke } return persistedEntity; + + bool ShouldTryLoadByCompositePrimaryKey() + { + if (compositeKeyValues.Count > 1) + { + return true; + } + + var resource = _dataManagementResourceContextProvider.Get()?.Resource; + var identifier = resource?.Entity?.Identifier; + + // If the entity doesn't have a surrogate key, proceed with load by primary key + if (identifier?.IsSurrogateIdentifier() != true) + { + return true; + } + + // If the surrogate primary key values are non-zero, proceed with load by primary key (i.e. USIs for existing people will be resolved already) + if ((int) compositeKeyValues[identifier.Properties[0].PropertyName]! != 0) + { + return true; + } + + return false; + } } string GetWhereClause(OrderedDictionary keyValues) diff --git a/Application/EdFi.Ods.Common/Models/Domain/EntityIdentifierExtensions.cs b/Application/EdFi.Ods.Common/Models/Domain/EntityIdentifierExtensions.cs index b832ae955..cf2b83fc0 100644 --- a/Application/EdFi.Ods.Common/Models/Domain/EntityIdentifierExtensions.cs +++ b/Application/EdFi.Ods.Common/Models/Domain/EntityIdentifierExtensions.cs @@ -38,7 +38,7 @@ public static bool IsSurrogateIdentifier(this EntityIdentifier entityIdentifier) { return entityIdentifier.IsPrimary && entityIdentifier.Properties.Count == 1 - && entityIdentifier.Properties.First().IsServerAssigned; + && entityIdentifier.Properties[0].IsServerAssigned; } ///