/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual InternalEntityTypeBuilder Apply(InternalEntityTypeBuilder entityTypeBuilder) { Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder)); var entityType = entityTypeBuilder.Metadata; if (entityType.BaseType != null || entityType.IsKeyless || !ConfigurationSource.Convention.Overrides(entityType.GetPrimaryKeyConfigurationSource())) { return(entityTypeBuilder); } List <Property> keyProperties = null; var definingFk = entityType.FindDefiningNavigation()?.ForeignKey ?? entityType.FindOwnership(); if (definingFk != null && definingFk.DeclaringEntityType != entityType) { definingFk = null; } if (definingFk?.IsUnique == true) { keyProperties = definingFk.Properties.ToList(); } if (keyProperties == null) { var candidateProperties = entityType.GetProperties().Where( p => !p.IsShadowProperty() || !ConfigurationSource.Convention.Overrides(p.GetConfigurationSource())).ToList(); keyProperties = (List <Property>)DiscoverKeyProperties(entityType, candidateProperties); if (keyProperties.Count > 1) { Logger?.MultiplePrimaryKeyCandidates(keyProperties[0], keyProperties[1]); return(entityTypeBuilder); } } if (definingFk?.IsUnique == false) { if (keyProperties.Count == 0 || definingFk.Properties.Contains(keyProperties.First())) { var shadowProperty = entityType.FindPrimaryKey()?.Properties.Last(); if (shadowProperty == null || entityType.FindPrimaryKey().Properties.Count == 1 || definingFk.Properties.Contains(shadowProperty)) { shadowProperty = entityTypeBuilder.CreateUniqueProperty("Id", typeof(int), isRequired: true); } keyProperties.Clear(); keyProperties.Add(shadowProperty); } var extraProperty = keyProperties[0]; keyProperties.RemoveAt(0); keyProperties.AddRange(definingFk.Properties); keyProperties.Add(extraProperty); } if (keyProperties.Count > 0) { entityTypeBuilder.PrimaryKey(keyProperties, ConfigurationSource.Convention); } return(entityTypeBuilder); }