public void Get_Value_delegates_to_Entry()
        {
            var internalEntryMock = CreateInternalEntryMock(Mock.Of<IProperty>());
            var columnModification = new ColumnModification(
                internalEntryMock.Object,
                new Mock<IProperty>().Object,
                new Mock<IRelationalPropertyAnnotations>().Object,
                new ParameterNameGenerator().GenerateNext,
                isRead: false,
                isWrite: false,
                isKey: false,
                isCondition: false);

            var value = columnModification.Value;

            internalEntryMock.Verify(m => m.GetCurrentValue(It.IsAny<IPropertyBase>()), Times.Once);
        }
        public void Set_Value_delegates_to_Entry()
        {
            var property = new Mock<IProperty>().Object;
            var internalEntryMock = CreateInternalEntryMock(property);
            var columnModification = new ColumnModification(
                internalEntryMock.Object,
                property,
                property.TestProvider(),
                new ParameterNameGenerator().GenerateNext,
                isRead: false,
                isWrite: false,
                isKey: false,
                isCondition: false);
            var value = new object();

            columnModification.Value = value;

            internalEntryMock.Verify(m => m.SetCurrentValue(property, It.IsAny<object>()), Times.Once);
        }
        public void Get_Value_delegates_to_Entry()
        {
            var property = new Model().AddEntityType(typeof(object)).AddProperty("Kake", typeof(string));

            var internalEntryMock = CreateInternalEntryMock(property);
            var columnModification = new ColumnModification(
                internalEntryMock.Object,
                new Mock<IProperty>().Object,
                new Mock<IRelationalPropertyAnnotations>().Object,
                new ParameterNameGenerator().GenerateNext,
                isRead: false,
                isWrite: false,
                isKey: false,
                isCondition: false,
                isConcurrencyToken: false);

            var value = columnModification.Value;

            internalEntryMock.Verify(m => m.GetCurrentValue(It.IsAny<IPropertyBase>()), Times.Once);
        }
        public void Parameters_return_set_values()
        {
            var columnModification = new ColumnModification(
                CreateInternalEntryMock(Mock.Of<IProperty>()).Object,
                new Mock<IProperty>().Object,
                new Mock<IRelationalPropertyAnnotations>().Object,
                new ParameterNameGenerator().GenerateNext,
                isRead: true,
                isWrite: true,
                isKey: true,
                isCondition: true);

            Assert.Null(columnModification.ColumnName);
            Assert.True(columnModification.IsRead);
            Assert.True(columnModification.IsWrite);
            Assert.True(columnModification.IsKey);
            Assert.True(columnModification.IsCondition);
            Assert.Equal("p0", columnModification.ParameterName);
            Assert.Equal("p1", columnModification.OriginalParameterName);
            Assert.Equal("p2", columnModification.OutputParameterName);
        }
        public void Parameters_return_set_values()
        {
            var property = new Model().AddEntityType(typeof(object)).AddProperty("Kake", typeof(string));

            var columnModification = new ColumnModification(
                CreateInternalEntryMock(property).Object,
                new Mock<IProperty>().Object,
                new Mock<IRelationalPropertyAnnotations>().Object,
                new ParameterNameGenerator().GenerateNext,
                isRead: true,
                isWrite: true,
                isKey: true,
                isCondition: true,
                isConcurrencyToken: false);

            Assert.Null(columnModification.ColumnName);
            Assert.True(columnModification.IsRead);
            Assert.True(columnModification.IsWrite);
            Assert.True(columnModification.IsKey);
            Assert.True(columnModification.IsCondition);
            Assert.Equal("p0", columnModification.ParameterName);
            Assert.Equal("p1", columnModification.OriginalParameterName);
        }
 protected override void AppendIdentityWhereCondition(StringBuilder commandStringBuilder, ColumnModification columnModification)
 {
 }
Пример #7
0
 protected abstract void AppendIdentityWhereCondition(
     [NotNull] StringBuilder commandStringBuilder,
     [NotNull] ColumnModification columnModification);
        private IReadOnlyList <ColumnModification> GenerateColumnModifications()
        {
            var state               = EntityState;
            var adding              = state == EntityState.Added;
            var updating            = state == EntityState.Modified;
            var columnModifications = new List <ColumnModification>();
            Dictionary <string, ColumnValuePropagator> sharedColumnMap = null;

            if (_entries.Count > 1 ||
                (_entries.Count == 1 && _entries[0].SharedIdentityEntry != null))
            {
                sharedColumnMap = new Dictionary <string, ColumnValuePropagator>();

                if (_comparer != null)
                {
                    _entries.Sort(_comparer);
                }

                foreach (var entry in _entries)
                {
                    if (entry.SharedIdentityEntry != null)
                    {
                        InitializeSharedColumns(entry.SharedIdentityEntry, updating, sharedColumnMap);
                    }

                    InitializeSharedColumns(entry, updating, sharedColumnMap);
                }
            }

            foreach (var entry in _entries)
            {
                var nonMainEntry = updating &&
                                   (entry.EntityState == EntityState.Deleted ||
                                    entry.EntityState == EntityState.Added);

                foreach (var property in entry.EntityType.GetProperties())
                {
                    var column = property.FindTableColumn(TableName, Schema);
                    if (column == null)
                    {
                        continue;
                    }

                    var isKey       = property.IsPrimaryKey();
                    var isCondition = !adding && (isKey || property.IsConcurrencyToken);
                    var readValue   = entry.IsStoreGenerated(property);
                    ColumnValuePropagator columnPropagator = null;
                    if (sharedColumnMap != null)
                    {
                        columnPropagator = sharedColumnMap[column.Name];
                    }

                    var writeValue = false;
                    if (!readValue)
                    {
                        if (adding)
                        {
                            writeValue = property.GetBeforeSaveBehavior() == PropertySaveBehavior.Save;
                        }
                        else if ((updating && property.GetAfterSaveBehavior() == PropertySaveBehavior.Save) ||
                                 (!isKey && nonMainEntry))
                        {
                            writeValue = columnPropagator?.TryPropagate(property, (InternalEntityEntry)entry)
                                         ?? entry.IsModified(property);
                        }
                    }

                    if (readValue ||
                        writeValue ||
                        isCondition)
                    {
                        if (readValue)
                        {
                            _requiresResultPropagation = true;
                        }

                        var columnModification = new ColumnModification(
                            entry,
                            property,
                            column,
                            _generateParameterName,
                            readValue,
                            writeValue,
                            isKey,
                            isCondition,
                            _sensitiveLoggingEnabled);

                        if (columnPropagator != null)
                        {
                            if (columnPropagator.ColumnModification != null)
                            {
                                columnPropagator.ColumnModification.AddSharedColumnModification(columnModification);

                                continue;
                            }

                            columnPropagator.ColumnModification = columnModification;
                        }

                        columnModifications.Add(columnModification);
                    }
                }
            }

            return(columnModifications);
        }
Пример #9
0
        private IReadOnlyList <ColumnModification> GenerateColumnModifications()
        {
            var adding = EntityState == EntityState.Added;
            var columnModifications = new List <ColumnModification>();

            if (_comparer != null)
            {
                _entries.Sort(_comparer);
            }

            var columnMap = _entries.Count == 1
                ? null
                : new Dictionary <string, ColumnModification>();

            Dictionary <IUpdateEntry, List <ColumnModification> > conflictingColumnValues         = null;
            Dictionary <IUpdateEntry, List <ColumnModification> > conflictingOriginalColumnValues = null;

            foreach (var entry in _entries)
            {
                Dictionary <string, IProperty> sharedIdentityEntryProperties = null;
                if (entry.SharedIdentityEntry != null)
                {
                    if (entry.EntityState == EntityState.Deleted)
                    {
                        continue;
                    }

                    sharedIdentityEntryProperties = new Dictionary <string, IProperty>();

                    foreach (var property in entry.SharedIdentityEntry.EntityType.GetProperties())
                    {
                        sharedIdentityEntryProperties[property.Relational().ColumnName] = property;
                    }
                }

                foreach (var property in entry.EntityType.GetProperties())
                {
                    var propertyAnnotations = property.Relational();
                    var isKey = property.IsPrimaryKey();
                    var isConcurrencyToken = property.IsConcurrencyToken;
                    var isCondition        = !adding && (isKey || isConcurrencyToken);
                    var readValue          = entry.IsStoreGenerated(property);

                    var writeValue = false;
                    if (!readValue)
                    {
                        if (adding)
                        {
                            writeValue = property.BeforeSaveBehavior == PropertySaveBehavior.Save;
                        }
                        else
                        {
                            if (property.AfterSaveBehavior == PropertySaveBehavior.Save &&
                                entry.IsModified(property))
                            {
                                writeValue = true;
                            }
                            else if (sharedIdentityEntryProperties != null &&
                                     (property.BeforeSaveBehavior == PropertySaveBehavior.Save ||
                                      property.AfterSaveBehavior == PropertySaveBehavior.Save))
                            {
                                writeValue = !sharedIdentityEntryProperties.TryGetValue(propertyAnnotations.ColumnName, out var originalProperty) ||
                                             !Equals(entry.SharedIdentityEntry.GetOriginalValue(originalProperty), entry.GetCurrentValue(property));
                            }
                        }
                    }

                    if (readValue ||
                        writeValue ||
                        isCondition)
                    {
                        if (readValue)
                        {
                            _requiresResultPropagation = true;
                        }

                        var columnModification = new ColumnModification(
                            entry,
                            property,
                            propertyAnnotations,
                            _generateParameterName,
                            readValue,
                            writeValue,
                            isKey,
                            isCondition,
                            isConcurrencyToken);

                        if (columnMap != null)
                        {
                            if (columnMap.TryGetValue(columnModification.ColumnName, out var existingColumnModification))
                            {
                                if (columnModification.UseCurrentValueParameter &&
                                    !Equals(columnModification.Value, existingColumnModification.Value))
                                {
                                    conflictingColumnValues = AddConflictingColumnValues(
                                        conflictingColumnValues, columnModification, existingColumnModification);
                                }
                                else if (columnModification.UseOriginalValueParameter &&
                                         !Equals(columnModification.OriginalValue, existingColumnModification.OriginalValue))
                                {
                                    conflictingOriginalColumnValues = AddConflictingColumnValues(
                                        conflictingOriginalColumnValues, columnModification, existingColumnModification);
                                }

                                continue;
                            }

                            columnMap.Add(columnModification.ColumnName, columnModification);
                        }

                        columnModifications.Add(columnModification);
                    }
                }
            }

            if (conflictingColumnValues != null)
            {
                var firstPair       = conflictingColumnValues.First();
                var firstEntry      = firstPair.Key;
                var firstProperties = firstPair.Value.Select(c => c.Property).ToList();
                var lastPair        = conflictingColumnValues.Last();
                var lastEntry       = lastPair.Key;
                var lastProperties  = lastPair.Value.Select(c => c.Property);

                if (_sensitiveLoggingEnabled)
                {
                    throw new InvalidOperationException(
                              RelationalStrings.ConflictingRowValuesSensitive(
                                  firstEntry.EntityType.DisplayName(),
                                  lastEntry.EntityType.DisplayName(),
                                  firstEntry.BuildCurrentValuesString(firstEntry.EntityType.FindPrimaryKey().Properties),
                                  firstEntry.BuildCurrentValuesString(firstProperties),
                                  lastEntry.BuildCurrentValuesString(lastProperties),
                                  firstProperties.FormatColumns()));
                }

                throw new InvalidOperationException(
                          RelationalStrings.ConflictingRowValues(
                              firstEntry.EntityType.DisplayName(),
                              lastEntry.EntityType.DisplayName(),
                              Property.Format(firstProperties),
                              Property.Format(lastProperties),
                              firstProperties.FormatColumns()));
            }

            if (conflictingOriginalColumnValues != null)
            {
                var firstPair       = conflictingOriginalColumnValues.First();
                var firstEntry      = firstPair.Key;
                var firstProperties = firstPair.Value.Select(c => c.Property).ToList();
                var lastPair        = conflictingOriginalColumnValues.Last();
                var lastEntry       = lastPair.Key;
                var lastProperties  = lastPair.Value.Select(c => c.Property);

                if (_sensitiveLoggingEnabled)
                {
                    throw new InvalidOperationException(
                              RelationalStrings.ConflictingOriginalRowValuesSensitive(
                                  firstEntry.EntityType.DisplayName(),
                                  lastEntry.EntityType.DisplayName(),
                                  firstEntry.BuildCurrentValuesString(firstEntry.EntityType.FindPrimaryKey().Properties),
                                  firstEntry.BuildOriginalValuesString(firstProperties),
                                  lastEntry.BuildOriginalValuesString(lastProperties),
                                  firstProperties.FormatColumns()));
                }

                throw new InvalidOperationException(
                          RelationalStrings.ConflictingOriginalRowValues(
                              firstEntry.EntityType.DisplayName(),
                              lastEntry.EntityType.DisplayName(),
                              Property.Format(firstProperties),
                              Property.Format(lastProperties),
                              firstProperties.FormatColumns()));
            }

            return(columnModifications);
        }
 protected override void AppendIdentityWhereCondition(StringBuilder commandStringBuilder, ColumnModification columnModification)
     => commandStringBuilder
         .Append(SqlGenerationHelper.DelimitIdentifier(columnModification.ColumnName))
         .Append(" = ")
         .Append("provider_specific_identity()");
Пример #11
0
 protected override void AppendIdentityWhereCondition(StringBuilder commandStringBuilder, ColumnModification columnModification)
 => commandStringBuilder
 .Append(SqlGenerationHelper.DelimitIdentifier(columnModification.ColumnName))
 .Append(" = ")
 .Append("provider_specific_identity()");