public virtual RelationalCommandBuilder AddParameter(
            [NotNull] string name,
            [CanBeNull] object value)
        {
            Check.NotEmpty(name, nameof(name));

            _parameters.Add(
                new RelationalParameter(
                    name,
                    value,
                    _typeMapper.GetMapping(value),
                    value?.GetType().IsNullableType() ?? null));

            return(this);
        }
예제 #2
0
        /// <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 AddDbParameter(DbCommand command, object value)
        {
            Check.NotNull(command, nameof(command));

            if (value == null)
            {
                command.Parameters
                .Add(_typeMapper.GetMappingForValue(null)
                     .CreateParameter(command, Name, null));

                return;
            }

            var dbParameter = value as DbParameter;

            if (dbParameter != null)
            {
                command.Parameters.Add(dbParameter);

                return;
            }

            var type = value.GetType();

            command.Parameters
            .Add(_typeMapper.GetMapping(type)
                 .CreateParameter(command, Name, value, type.IsNullableType()));
        }
 /// <summary>
 ///     Gets the relational database type for a given object, throwing if no mapping is found.
 /// </summary>
 /// <param name="typeMapper"> The type mapper. </param>
 /// <param name="value"> The object to get the mapping for. </param>
 /// <returns> The type mapping to be used. </returns>
 public static RelationalTypeMapping GetMappingForValue(
     [CanBeNull] this IRelationalTypeMapper typeMapper,
     [CanBeNull] object value)
 => value == null ||
 value == DBNull.Value ||
 typeMapper == null
         ? RelationalTypeMapping.NullMapping
         : typeMapper.GetMapping(value.GetType());
예제 #4
0
        private string GetTypeNameForCopy(IProperty property)
        {
            var typeName = property.SqlServer().ColumnType
                           ?? _typeMapper.GetMapping(property).StoreType;

            return(typeName.Equals("rowversion", StringComparison.OrdinalIgnoreCase) ||
                   typeName.Equals("timestamp", StringComparison.OrdinalIgnoreCase)
                ? (property.IsNullable ? "varbinary(8)" : "binary(8)")
                : typeName);
        }
예제 #5
0
        protected virtual PropertyBuilder VisitColumn([NotNull] EntityTypeBuilder builder, [NotNull] ColumnModel column)
        {
            Check.NotNull(builder, nameof(builder));
            Check.NotNull(column, nameof(column));

            var mapping = column.DataType != null
                ? _typeMapper.FindMapping(column.DataType)
                : null;

            if (mapping?.ClrType == null)
            {
                Logger.LogWarning(RelationalDesignStrings.CannotFindTypeMappingForColumn(column.DisplayName, column.DataType));
                return(null);
            }

            var clrType = column.IsNullable ? mapping.ClrType.MakeNullable() : mapping.ClrType;

            var property = builder.Property(clrType, GetPropertyName(column));

            if (_typeMapper.GetMapping(property.Metadata).DefaultTypeName != column.DataType &&
                !string.IsNullOrWhiteSpace(column.DataType))
            {
                property.HasColumnType(column.DataType);
            }

            property.HasColumnName(column.Name);

            if (column.MaxLength.HasValue)
            {
                property.HasMaxLength(column.MaxLength.Value);
            }

            if (column.ValueGenerated == ValueGenerated.OnAdd)
            {
                property.ValueGeneratedOnAdd();
            }

            if (column.ValueGenerated == ValueGenerated.OnAddOrUpdate)
            {
                property.ValueGeneratedOnAddOrUpdate();
            }

            if (column.DefaultValue != null)
            {
                property.HasDefaultValueSql(column.DefaultValue);
            }

            if (!column.PrimaryKeyOrdinal.HasValue)
            {
                property.IsRequired(!column.IsNullable);
            }

            return(property);
        }
예제 #6
0
        private string GetTypeNameForCopy(IProperty property)
        {
            var mapping  = _typeMapper.GetMapping(property);
            var typeName = mapping.DefaultTypeName;

            if (property.IsConcurrencyToken &&
                (typeName.Equals("rowversion", StringComparison.OrdinalIgnoreCase) ||
                 typeName.Equals("timestamp", StringComparison.OrdinalIgnoreCase)))
            {
                return(property.IsNullable ? "varbinary(8)" : "binary(8)");
            }

            return(typeName);
        }
        protected virtual void Generate(
            [NotNull] CreateSequenceOperation operation,
            [CanBeNull] IModel model,
            [NotNull] RelationalCommandListBuilder builder)
        {
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            builder
            .Append("CREATE SEQUENCE ")
            .Append(SqlGenerator.DelimitIdentifier(operation.Name, operation.Schema));

            if (operation.ClrType != typeof(long))
            {
                builder
                .Append(" AS ")
                .Append(_typeMapper.GetMapping(operation.ClrType).DefaultTypeName);
            }

            builder
            .Append(" START WITH ")
            .Append(SqlGenerator.GenerateLiteral(operation.StartValue));
            SequenceOptions(operation, model, builder);
        }
 public static bool TryGetMapping(
     [NotNull] this IRelationalTypeMapper typeMapper,
     [NotNull] string typeName,
     [CanBeNull] out RelationalTypeMapping mapping)
 {
     try
     {
         mapping = typeMapper.GetMapping(typeName);
         return(mapping != null);
     }
     catch
     {
         mapping = null;
         return(false);
     }
 }
예제 #9
0
        /// <summary>
        ///     Creates a new <see cref="TypeMaterializationInfo" /> instance.
        /// </summary>
        /// <param name="modelType"> The type that is needed in the model after conversion. </param>
        /// <param name="property"> The property associated with the type, or <c>null</c> if none. </param>
        /// <param name="typeMapper"> The type mapper to use to find a mapping if the property does not have one already bound. </param>
        /// <param name="index">
        ///     The index of the underlying result set that should be used for this type,
        ///     or -1 if no index mapping is needed.
        /// </param>
        public TypeMaterializationInfo(
            [NotNull] Type modelType,
            [CanBeNull] IProperty property,
            [CanBeNull] IRelationalTypeMapper typeMapper,
            int index = -1)
        {
            Check.NotNull(modelType, nameof(modelType));

            var mapping = property?.FindRelationalMapping()
                          ?? typeMapper?.GetMapping(modelType);

            StoreType = mapping?.Converter?.StoreType
                        ?? modelType.UnwrapNullableType().UnwrapEnumType();

            ModelType = modelType;
            Mapping   = mapping;
            Property  = property;
            Index     = index;
        }
        private SpannerCommand CreateSpannerCommand(
            SpannerConnection spannerConnection,
            SpannerTransaction transaction,
            ModificationCommand modificationCommand)
        {
            SpannerCommand cmd;

            switch (modificationCommand.EntityState)
            {
            case EntityState.Deleted:
                cmd = spannerConnection.CreateDeleteCommand(modificationCommand.TableName);
                break;

            case EntityState.Modified:
                cmd = spannerConnection.CreateUpdateCommand(modificationCommand.TableName);
                break;

            case EntityState.Added:
                cmd = spannerConnection.CreateInsertCommand(modificationCommand.TableName);
                break;

            default:
                throw new NotSupportedException(
                          $"Modification type {modificationCommand.EntityState} is not supported.");
            }
            cmd.Logger      = new SpannerLogBridge <DbLoggerCategory.Database.Command>(_logger);
            cmd.Transaction = transaction;
            foreach (var columnModification in modificationCommand.ColumnModifications)
            {
                cmd.Parameters.Add(
                    _typeMapper.GetMapping(columnModification.Property).CreateParameter(cmd,
                                                                                        columnModification.ColumnName,
                                                                                        columnModification.UseOriginalValueParameter
                            ? columnModification.OriginalValue
                            : columnModification.Value, columnModification.Property.IsNullable));
            }
            return(cmd);
        }
예제 #11
0
 string GetColumnType(ColumnModification column)
 {
     return(_typeMapper.GetMapping(column.Property).StoreType);
 }
예제 #12
0
        protected override void ColumnDefinition(
            string schema,
            string table,
            string name,
            Type clrType,
            string type,
            bool?unicode,
            int?maxLength,
            bool rowVersion,
            bool nullable,
            object defaultValue,
            string defaultValueSql,
            string computedColumnSql,
            IAnnotatable annotatable,
            IModel model,
            MigrationCommandListBuilder builder)
        {
            ThrowIf.Argument.IsEmpty(name, "name");
            ThrowIf.Argument.IsNull(clrType, "clrType");
            ThrowIf.Argument.IsNull(annotatable, "annotatable");
            ThrowIf.Argument.IsNull(builder, "builder");


            var property = FindProperty(model, schema, table, name);

            if (type == null)
            {
                //Any property that maps to the column will work
                type = property != null
           ? _typeMapper.GetMapping(property).StoreType
           : _typeMapper.GetMapping(clrType).StoreType;
            }

            var charset = property?.FindAnnotation(MySQLAnnotationNames.Charset);

            if (charset != null)
            {
                type += $" CHARACTER SET {charset.Value}";
            }

            var collation = property?.FindAnnotation(MySQLAnnotationNames.Collation);

            if (collation != null)
            {
                type += $" COLLATE {collation.Value}";
            }

            if (computedColumnSql != null)
            {
                builder
                .Append(_sqlGenerationHelper.DelimitIdentifier(name))
                .Append(string.Format(" {0} AS ", type))
                .Append(" (" + computedColumnSql + ")");

                return;
            }

            var autoInc = annotatable[MySQLAnnotationNames.AutoIncrement];

            base.ColumnDefinition(
                schema, table, name, clrType, type, unicode, maxLength, rowVersion, nullable,
                defaultValue, defaultValueSql, computedColumnSql, annotatable, model, builder);

            if (autoInc != null && (bool)autoInc)
            {
                builder.Append(" AUTO_INCREMENT");
            }
        }
        /// <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 TypeScaffoldingInfo FindMapping(
            string storeType,
            bool keyOrIndex,
            bool rowVersion)
        {
            // This is because certain providers can have no type specified as a default type e.g. SQLite
            Check.NotNull(storeType, nameof(storeType));

            var mapping = _typeMapper.FindMapping(storeType);

            if (mapping == null)
            {
                return(null);
            }

            var  canInfer          = false;
            bool?scaffoldUnicode   = null;
            int? scaffoldMaxLength = null;

            if (mapping.ClrType == typeof(byte[]) &&
                _typeMapper.ByteArrayMapper != null)
            {
                // Check for inference
                var byteArrayMapping = _typeMapper.ByteArrayMapper.FindMapping(rowVersion, keyOrIndex, mapping.Size);

                if (byteArrayMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase))
                {
                    canInfer = true;

                    // Check for size
                    var sizedMapping = _typeMapper.ByteArrayMapper.FindMapping(rowVersion, keyOrIndex, size: null);
                    scaffoldMaxLength = sizedMapping.Size != byteArrayMapping.Size ? byteArrayMapping.Size : null;
                }
            }
            else if (mapping.ClrType == typeof(string) &&
                     _typeMapper.StringMapper != null)
            {
                // Check for inference
                var stringMapping = _typeMapper.StringMapper.FindMapping(mapping.IsUnicode, keyOrIndex, mapping.Size);

                if (stringMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase))
                {
                    canInfer = true;

                    // Check for unicode
                    var unicodeMapping = _typeMapper.StringMapper.FindMapping(unicode: true, keyOrIndex: keyOrIndex, maxLength: mapping.Size);
                    scaffoldUnicode = unicodeMapping.IsUnicode != stringMapping.IsUnicode ? (bool?)stringMapping.IsUnicode : null;

                    // Check for size
                    var sizedMapping = _typeMapper.StringMapper.FindMapping(mapping.IsUnicode, keyOrIndex, maxLength: null);
                    scaffoldMaxLength = sizedMapping.Size != stringMapping.Size ? stringMapping.Size : null;
                }
            }
            else
            {
                var defaultMapping = _typeMapper.GetMapping(mapping.ClrType);

                if (defaultMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase))
                {
                    canInfer = true;
                }
            }

            return(new TypeScaffoldingInfo(
                       mapping.ClrType,
                       canInfer,
                       scaffoldUnicode,
                       scaffoldMaxLength));
        }
예제 #14
0
        protected virtual void EnsureSharedColumnsCompatibility([NotNull] IModel model)
        {
            var groupedEntityTypes = new Dictionary <string, List <IEntityType> >();

            foreach (var entityType in model.GetEntityTypes())
            {
                var annotations = _relationalExtensions.For(entityType);
                var tableName   = annotations.Schema + "." + annotations.TableName;
                if (!groupedEntityTypes.ContainsKey(tableName))
                {
                    groupedEntityTypes[tableName] = new List <IEntityType>();
                }
                groupedEntityTypes[tableName].Add(entityType);
            }

            foreach (var table in groupedEntityTypes.Keys)
            {
                var properties           = groupedEntityTypes[table].SelectMany(et => et.GetDeclaredProperties());
                var propertyTypeMappings = new Dictionary <string, IProperty>();

                foreach (var property in properties)
                {
                    var       propertyAnnotations = _relationalExtensions.For(property);
                    var       columnName          = propertyAnnotations.ColumnName;
                    IProperty duplicateProperty;
                    if (propertyTypeMappings.TryGetValue(columnName, out duplicateProperty))
                    {
                        var previousAnnotations = _relationalExtensions.For(duplicateProperty);
                        var currentTypeString   = propertyAnnotations.ColumnType
                                                  ?? _typeMapper.GetMapping(property).DefaultTypeName;
                        var previousTypeString = previousAnnotations.ColumnType
                                                 ?? _typeMapper.GetMapping(duplicateProperty).DefaultTypeName;
                        if (!currentTypeString.Equals(previousTypeString, StringComparison.OrdinalIgnoreCase))
                        {
                            ShowError(RelationalStrings.DuplicateColumnName(
                                          duplicateProperty.DeclaringEntityType.DisplayName(),
                                          duplicateProperty.Name,
                                          property.DeclaringEntityType.DisplayName(),
                                          property.Name,
                                          columnName,
                                          table,
                                          previousTypeString,
                                          currentTypeString));
                        }

                        if (property.IsColumnNullable() != duplicateProperty.IsColumnNullable())
                        {
                            ShowError(RelationalStrings.DuplicateColumnNameNullabilityMismatch(
                                          duplicateProperty.DeclaringEntityType.DisplayName(),
                                          duplicateProperty.Name,
                                          property.DeclaringEntityType.DisplayName(),
                                          property.Name,
                                          columnName,
                                          table));
                        }

                        var currentComputedValueSql  = propertyAnnotations.ComputedValueSql ?? "";
                        var previousComputedValueSql = previousAnnotations.ComputedValueSql ?? "";
                        if (!currentComputedValueSql.Equals(previousComputedValueSql, StringComparison.OrdinalIgnoreCase))
                        {
                            ShowError(RelationalStrings.DuplicateColumnNameComputedSqlMismatch(
                                          duplicateProperty.DeclaringEntityType.DisplayName(),
                                          duplicateProperty.Name,
                                          property.DeclaringEntityType.DisplayName(),
                                          property.Name,
                                          columnName,
                                          table,
                                          previousComputedValueSql,
                                          currentComputedValueSql));
                        }

                        var currentDefaultValue  = propertyAnnotations.DefaultValue;
                        var previousDefaultValue = previousAnnotations.DefaultValue;
                        if (currentDefaultValue != previousDefaultValue)
                        {
                            ShowError(RelationalStrings.DuplicateColumnNameDefaultSqlMismatch(
                                          duplicateProperty.DeclaringEntityType.DisplayName(),
                                          duplicateProperty.Name,
                                          property.DeclaringEntityType.DisplayName(),
                                          property.Name,
                                          columnName,
                                          table,
                                          previousDefaultValue ?? "NULL",
                                          currentDefaultValue ?? "NULL"));
                        }

                        var currentDefaultValueSql  = propertyAnnotations.DefaultValueSql ?? "";
                        var previousDefaultValueSql = previousAnnotations.DefaultValueSql ?? "";
                        if (!currentDefaultValueSql.Equals(previousDefaultValueSql, StringComparison.OrdinalIgnoreCase))
                        {
                            ShowError(RelationalStrings.DuplicateColumnNameDefaultSqlMismatch(
                                          duplicateProperty.DeclaringEntityType.DisplayName(),
                                          duplicateProperty.Name,
                                          property.DeclaringEntityType.DisplayName(),
                                          property.Name,
                                          columnName,
                                          table,
                                          previousDefaultValueSql,
                                          currentDefaultValueSql));
                        }
                    }
                    else
                    {
                        propertyTypeMappings[columnName] = property;
                    }
                }
            }
        }