private static InternalEntityEntry TryPropagateValue(InternalEntityEntry entry, IProperty property) { var entityType = entry.EntityType; var stateManager = entry.StateManager; foreach (var foreignKey in entityType.GetForeignKeys()) { for (var propertyIndex = 0; propertyIndex < foreignKey.Properties.Count; propertyIndex++) { if (property == foreignKey.Properties[propertyIndex]) { // Remove when issue #749 is fixed var principal = foreignKey.DependentToPrincipal?.IsShadowProperty ?? true ? null : foreignKey.DependentToPrincipal.GetGetter().GetClrValue(entry.Entity); InternalEntityEntry principalEntry = null; if (principal != null) { principalEntry = stateManager.GetOrCreateEntry(principal); } else if (foreignKey.PrincipalToDependent != null) { foreach (var danglerEntry in stateManager.GetRecordedReferers(entry.Entity, clear: false)) { if (danglerEntry.Item1 == foreignKey.PrincipalToDependent) { principalEntry = danglerEntry.Item2; break; } } } if (principalEntry != null) { var principalProperty = foreignKey.PrincipalKey.Properties[propertyIndex]; var principalValue = principalEntry[principalProperty]; if (!principalProperty.ClrType.IsDefaultValue(principalValue)) { entry[property] = principalValue; if (principalEntry.HasTemporaryValue(principalProperty)) { entry.MarkAsTemporary(property); } else { entry.MarkAsTemporary(property, isTemporary: false); } return(principalEntry); } } break; } } } return(null); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual async Task <InternalEntityEntry> PropagateValueAsync( InternalEntityEntry entry, IProperty property, CancellationToken cancellationToken = default) { Debug.Assert(property.IsForeignKey()); var principalEntry = TryPropagateValue(entry, property); if (principalEntry == null && property.IsKey()) { var valueGenerator = TryGetValueGenerator(property); if (valueGenerator != null) { entry[property] = await valueGenerator.NextAsync(new EntityEntry(entry), cancellationToken); if (valueGenerator.GeneratesTemporaryValues) { entry.MarkAsTemporary(property); } } } return(principalEntry); }
private static void SetGeneratedValue(InternalEntityEntry entry, IProperty property, object generatedValue, bool isTemporary) { if (generatedValue != null) { entry[property] = generatedValue; if (isTemporary) { entry.MarkAsTemporary(property); } } }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void PropagateValue(InternalEntityEntry entry, IProperty property) { Debug.Assert(property.IsForeignKey()); if (!TryPropagateValue(entry, property) && property.IsKey()) { var valueGenerator = TryGetValueGenerator(property); if (valueGenerator != null) { entry[property] = valueGenerator.Next(new EntityEntry(entry)); if (valueGenerator.GeneratesTemporaryValues) { entry.MarkAsTemporary(property); } } } }