/// <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> protected virtual IEnumerable <ModificationCommand> CreateModificationCommands( [NotNull] IReadOnlyList <IUpdateEntry> entries, [NotNull] Func <string> generateParameterName) { var commands = new List <ModificationCommand>(); if (_sharedTableEntryMapFactories == null) { _sharedTableEntryMapFactories = SharedTableEntryMap <ModificationCommand> .CreateSharedTableEntryMapFactories(entries[0].EntityType.Model, StateManager); } Dictionary <(string Schema, string Name), SharedTableEntryMap <ModificationCommand> > sharedTablesCommandsMap = null; foreach (var entry in entries) { var entityType = entry.EntityType; var relationalExtensions = entityType.Relational(); var table = relationalExtensions.TableName; var schema = relationalExtensions.Schema; var tableKey = (schema, table); ModificationCommand command; if (_sharedTableEntryMapFactories.TryGetValue(tableKey, out var commandIdentityMapFactory)) { if (sharedTablesCommandsMap == null) { sharedTablesCommandsMap = new Dictionary <(string Schema, string Name), SharedTableEntryMap <ModificationCommand> >(); } if (!sharedTablesCommandsMap.TryGetValue(tableKey, out var sharedCommandsMap)) { sharedCommandsMap = commandIdentityMapFactory((t, s, c) => new ModificationCommand( t, s, generateParameterName, _sensitiveLoggingEnabled, c)); sharedTablesCommandsMap.Add((schema, table), sharedCommandsMap); } command = sharedCommandsMap.GetOrAddValue(entry); } else { command = new ModificationCommand( table, schema, generateParameterName, _sensitiveLoggingEnabled, comparer: null); } command.AddEntry(entry); commands.Add(command); } if (sharedTablesCommandsMap != null) { Validate(sharedTablesCommandsMap); } return(commands.Where( c => c.EntityState != EntityState.Modified || c.ColumnModifications.Any(m => m.IsWrite))); }
/// <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> protected virtual IEnumerable <ModificationCommand> CreateModificationCommands( [NotNull] IList <IUpdateEntry> entries, [NotNull] IUpdateAdapter updateAdapter, [NotNull] Func <string> generateParameterName) { var commands = new List <ModificationCommand>(); if (_sharedTableEntryMapFactories == null) { _sharedTableEntryMapFactories = SharedTableEntryMap <ModificationCommand> .CreateSharedTableEntryMapFactories(updateAdapter.Model, updateAdapter); } Dictionary <(string Name, string Schema), SharedTableEntryMap <ModificationCommand> > sharedTablesCommandsMap = null; foreach (var entry in entries) { if (entry.SharedIdentityEntry != null && entry.EntityState == EntityState.Deleted) { continue; } var entityType = entry.EntityType; var table = entityType.GetTableName(); var schema = entityType.GetSchema(); var tableKey = (table, schema); ModificationCommand command; var isMainEntry = true; if (_sharedTableEntryMapFactories.TryGetValue(tableKey, out var commandIdentityMapFactory)) { if (sharedTablesCommandsMap == null) { sharedTablesCommandsMap = new Dictionary <(string, string), SharedTableEntryMap <ModificationCommand> >(); } if (!sharedTablesCommandsMap.TryGetValue(tableKey, out var sharedCommandsMap)) { sharedCommandsMap = commandIdentityMapFactory( (n, s, c) => new ModificationCommand( n, s, generateParameterName, _sensitiveLoggingEnabled, c)); sharedTablesCommandsMap.Add(tableKey, sharedCommandsMap); } command = sharedCommandsMap.GetOrAddValue(entry); isMainEntry = sharedCommandsMap.IsMainEntityType(entry.EntityType.GetRootType()); } else { command = new ModificationCommand( table, schema, generateParameterName, _sensitiveLoggingEnabled, comparer: null); } command.AddEntry(entry, isMainEntry); commands.Add(command); } if (sharedTablesCommandsMap != null) { AddUnchangedSharingEntries(sharedTablesCommandsMap.Values, entries); } return(commands.Where( c => c.EntityState != EntityState.Modified || c.ColumnModifications.Any(m => m.IsWrite))); }
/// <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> protected virtual IEnumerable <ModificationCommand> CreateModificationCommands( [NotNull] IList <IUpdateEntry> entries, [NotNull] IUpdateAdapter updateAdapter, [NotNull] Func <string> generateParameterName) { var commands = new List <ModificationCommand>(); if (_sharedTableEntryMapFactories == null) { _sharedTableEntryMapFactories = SharedTableEntryMap <ModificationCommand> .CreateSharedTableEntryMapFactories(updateAdapter.Model, updateAdapter); } Dictionary <(string Name, string Schema), SharedTableEntryMap <ModificationCommand> > sharedTablesCommandsMap = null; foreach (var entry in entries) { if (entry.SharedIdentityEntry != null && entry.EntityState == EntityState.Deleted) { continue; } var mappings = (IReadOnlyCollection <ITableMapping>)entry.EntityType.GetTableMappings(); var mappingCount = mappings.Count; ModificationCommand mainCommand = null; var relatedCommands = mappingCount > 1 ? new List <ModificationCommand>(mappingCount - 1) : null; foreach (var mapping in mappings) { var table = mapping.Table; var tableKey = (table.Name, table.Schema); ModificationCommand command; var isMainEntry = true; if (_sharedTableEntryMapFactories.TryGetValue(tableKey, out var commandIdentityMapFactory)) { if (sharedTablesCommandsMap == null) { sharedTablesCommandsMap = new Dictionary <(string, string), SharedTableEntryMap <ModificationCommand> >(); } if (!sharedTablesCommandsMap.TryGetValue(tableKey, out var sharedCommandsMap)) { sharedCommandsMap = commandIdentityMapFactory( (n, s, c) => new ModificationCommand( n, s, generateParameterName, _sensitiveLoggingEnabled, c)); sharedTablesCommandsMap.Add(tableKey, sharedCommandsMap); } command = sharedCommandsMap.GetOrAddValue(entry); isMainEntry = sharedCommandsMap.IsMainEntry(entry); } else { command = new ModificationCommand( table.Name, table.Schema, generateParameterName, _sensitiveLoggingEnabled, comparer: null); } command.AddEntry(entry, isMainEntry); commands.Add(command); if (mapping.IsMainTableMapping) { Check.DebugAssert(mainCommand == null, "mainCommand == null"); mainCommand = command; } else if (relatedCommands != null) { relatedCommands.Add(command); } } if (mainCommand == null) { throw new InvalidOperationException(RelationalStrings.ReadonlyEntitySaved(entry.EntityType.DisplayName())); } if (relatedCommands != null) { foreach (var relatedCommand in relatedCommands) { relatedCommand.Predecessor = mainCommand; } } } if (sharedTablesCommandsMap != null) { AddUnchangedSharingEntries(sharedTablesCommandsMap.Values, entries); } return(commands); }