예제 #1
0
        private static void SetValueToCommandParameter(object entity, IPropertyGetterDictionary getters, string propertyName, IDbDataParameter param)
        {
            var getter = getters[propertyName];

            if (getter == null)
            {
                return;
            }
            object fieldValue = getter(entity);
            var    nullable   = fieldValue as INullable;

            if (nullable != null && nullable.IsNull)
            {
                param.Value = DBNull.Value;
            }
            else
            {
                if (fieldValue != null && (param.DbType == DbType.String || param.DbType == DbType.AnsiString) && !(fieldValue is string))
                {
                    var convertible = fieldValue as IConvertible;
                    if (convertible != null)
                    {
                        fieldValue = convertible.ToString(CultureInfo.InvariantCulture);
                    }
                    else
                    {
                        fieldValue = fieldValue.ToString();
                    }
                }
                param.Value = fieldValue ?? DBNull.Value;
            }
        }
예제 #2
0
        /// <summary>
        /// Representa un mapeo entre los ordinales de los campos del IDataReader y los Getters.
        /// Devuelve un array en el que su índice y el de los ordinales de los campos del
        /// IDataReader tienen que coincidir.
        /// </summary>
        /// <param name="reader">Estructura de datos que contiene los datos obtenidos de la BD.</param>
        /// <param name="itemType">Tipo de datos cuyas propiedades deben estar mapeadas con los
        /// campos de la BD.</param>
        /// <returns>Vector de Getters.</returns>
        private static PropertyGetter[] GetPropertyGetters(IDataReader reader, Type itemType)
        {
            int fieldCount = reader.FieldCount;

            PropertyGetter[] propertyGetters = new PropertyGetter[fieldCount];

            //Posiblemente esta en la cache y lo devuelve, sino se crea y se devuelve.
            IPropertyGetterDictionary gettersDictionary = PropertyHelper.GetPropertyGetters(itemType);

            //Recorremos todos los campos del IDataReader
            for (int fieldOrdinal = 0; fieldOrdinal < fieldCount; fieldOrdinal++)
            {
                PropertyGetter getter;

                //Mapeo entre ordinal del campo y el nombre de la propiedad de la clase.
                //Aqui es importante que los campos del IDataReader se llamen exactamente
                //igual que las propiedades de la clase. Puesto que se buscará el nombre del
                //campo en el diccionario creado a partir de las propiedades de la clase.
                if (gettersDictionary.TryGetValue(reader.GetName(fieldOrdinal), out getter))
                {
                    propertyGetters[fieldOrdinal] = getter;
                }
            }
            return(propertyGetters);
        }
예제 #3
0
        private PropertyGetter[] GetPropertyGetters()
        {
            PropertyGetter[]          getters         = new PropertyGetter[this.properties.Length];
            IPropertyGetterDictionary propertyGetters = PropertyHelper.GetPropertyGetters(this.itemType);
            int propertyCount = this.properties.Length;

            for (int index = 0; index < propertyCount; index++)
            {
                getters[index] = propertyGetters[properties[index].Name];
            }
            return(getters);
        }
예제 #4
0
        private void GenerateUpdateSetClause(object entity, IEnumerable <string> fieldsToUpdate, EntityMetadata entityMetadata, IPropertyGetterDictionary getters, DbCommand cmd, StringBuilder commandText, ref bool hasEntityRowVersionField)
        {
            bool firstTime = true;

            foreach (var propertyName in fieldsToUpdate)
            {
                PropertyMetadata propMetadata = null;
                if (!entityMetadata.UpdatableProperties.TryGetValue(propertyName, out propMetadata))
                {
                    continue;
                }
                SqlFieldAttribute field = propMetadata.SqlField;
                if (!field.IsKey &&
                    !string.Equals(propertyName, DataService.SpecialFieldNames.CreatedByFieldName, StringComparison.OrdinalIgnoreCase) &&
                    !string.Equals(propertyName, DataService.SpecialFieldNames.CreatedDateFieldName, StringComparison.OrdinalIgnoreCase)
                    )
                {
                    if (firstTime)
                    {
                        commandText.Append(" SET\n    ");
                        firstTime = false;
                    }
                    else
                    {
                        commandText.Append(",\n    ");
                    }
                    if (string.Equals(propertyName, DataService.SpecialFieldNames.EntityRowVersionFieldName, StringComparison.OrdinalIgnoreCase))
                    {
                        hasEntityRowVersionField = true;
                        commandText.Append(this.DataService.EntityLiteProvider.StartQuote + propMetadata.SqlField.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote).Append(" = ")
                        .Append(this.DataService.EntityLiteProvider.StartQuote + propMetadata.SqlField.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote).Append(" + 1");
                    }
                    else if (propertyName == DataService.SpecialFieldNames.DbChangeNumberFieldName)
                    {
                        commandText.Append(this.DataService.EntityLiteProvider.StartQuote + propMetadata.SqlField.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote).Append(" = ")
                        .Append(DataService.EntityLiteProvider.GetNextValExpression(GetDbChangeNumberFullSequenceName()));
                    }
                    else
                    {
                        string           parameterName;
                        IDbDataParameter param = CreateParameter(propMetadata, propertyName, out parameterName);
                        commandText.Append(this.DataService.EntityLiteProvider.StartQuote + field.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote)
                        .Append(" = ").Append(parameterName);

                        object fieldValue = getters[propertyName](entity);
                        SetValueToCommandParameter(entity, getters, propertyName, param);
                        cmd.Parameters.Add(param);
                    }
                }
            }
        }
예제 #5
0
        private static void SetParameterValuesFromObject(DbCommand command, object obj, EntityMetadata entityMetadata)
        {
            IPropertyGetterDictionary getters = entityMetadata.Getters;
            var parameters = command.Parameters;
            var count      = parameters.Count;

            for (int i = 0; i < count; i++)
            {
                var param = parameters[i];
                if ((param.Direction & ParameterDirection.Input) == ParameterDirection.Input)
                {
                    SetValueToCommandParameter(obj, getters, param.SourceColumn, param);
                }
            }
        }
예제 #6
0
        private PropertyGetter[] GetPropertyGetters()
        {
            PropertyGetter[]          getters         = new PropertyGetter[this.properties.Length];
            IPropertyGetterDictionary propertyGetters = PropertyHelper.GetPropertyGetters(this.itemType);
            int propertyCount = this.properties.Length;

            for (int index = 0; index < propertyCount; index++)
            {
                var property = properties[index];
                getters[index] = propertyGetters[property.Name];
                var propertyTypeName = property.PropertyType.Name;
                if (propertyTypeName == "JToken" || propertyTypeName == "JObject")
                {
                    getters[index] = ToStringGetter(getters[index]);
                }
            }
            return(getters);
        }
예제 #7
0
        private DbCommand GenerateUpdateCommand(object entity, IEnumerable <string> fieldsToUpdate)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            if (fieldsToUpdate == null)
            {
                throw new ArgumentNullException(nameof(fieldsToUpdate));
            }

            Type           entityType     = entity.GetType();
            EntityMetadata entityMetadata = entityType.GetEntityMetadata();
            string         baseTable      = entityMetadata.BaseTableName;

            if (string.IsNullOrEmpty(baseTable))
            {
                throw new InvalidOperationException("cannot generate update command for entity " + entityType.Name + " because it does not have a base table");
            }
            if (entityMetadata.PrimaryKeyPropertyNames.Count == 0)
            {
                throw new InvalidOperationException("cannot generate update command for entity " + entityType.Name + " because it does not have a primary key");
            }

            string fullTableName = entityMetadata.GetFullTableName(this.DataService.EntityLiteProvider.DefaultSchema, this.DataService.EntityLiteProvider.StartQuote, this.DataService.EntityLiteProvider.EndQuote);

            IPropertyGetterDictionary getters = PropertyHelper.GetPropertyGetters(entityType);
            DbCommand     cmd         = DataService.EntityLiteProvider.CreateCommand();
            StringBuilder commandText = new StringBuilder();

            commandText.Append("\nUPDATE ").Append(fullTableName);

            bool hasEntityRowVersionField = false;

            GenerateUpdateSetClause(entity, fieldsToUpdate, entityMetadata, getters, cmd, commandText, ref hasEntityRowVersionField);
            GenerateUpdateWhereClauseWithPrimaryKeyAndEntityRowVersion(entity, entityMetadata, getters, cmd, commandText, hasEntityRowVersionField);
            if (this.DataService.IsPreventingSuperfluousUpdatesEnabled)
            {
                AddModifiedFieldsPredicateToToUpdateWhereClause(fieldsToUpdate, entityMetadata, commandText);
            }
            cmd.CommandText = commandText.ToString();
            return(cmd);
        }
예제 #8
0
        public static bool IsEqualsTo <T>(this T obj, T other) where T : class
        {
            if (obj == null && other == null)
            {
                return(true);
            }
            if (obj == null || other == null)
            {
                return(false);
            }
            IPropertyGetterDictionary getters = PropertyHelper.GetPropertyGetters(typeof(T));

            foreach (var kv in getters)
            {
                if (!object.Equals(kv.Value(obj), kv.Value(other)))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #9
0
        private DbCommand GenerateDeleteCommand(object entity)
        {
            try
            {
                if (entity == null)
                {
                    throw new ArgumentNullException(nameof(entity));
                }
                Type           entityType     = entity.GetType();
                EntityMetadata entityMetadata = entityType.GetEntityMetadata();
                if (entityMetadata == null)
                {
                    throw new InvalidOperationException("cannot generate delete command for entity " + entityType.Name + " because it does not have metadata");
                }
                string baseTable = entityMetadata.BaseTableName;
                if (string.IsNullOrEmpty(baseTable))
                {
                    throw new InvalidOperationException("cannot generate delete command for entity " + entityType.Name + " because it does not have a base table");
                }
                if (entityMetadata.PrimaryKeyPropertyNames.Count == 0)
                {
                    throw new InvalidOperationException("cannot generate delete command for entity " + entityType.Name + " because it does not have a primary key");
                }
                IPropertyGetterDictionary getters = PropertyHelper.GetPropertyGetters(entityType);
                DbCommand     cmd           = DataService.EntityLiteProvider.CreateCommand();
                StringBuilder commandText   = new StringBuilder();
                string        fullTableName = entityMetadata.GetFullTableName(this.DataService.EntityLiteProvider.DefaultSchema, this.DataService.EntityLiteProvider.StartQuote, this.DataService.EntityLiteProvider.EndQuote);
                commandText.Append("\nDELETE FROM ").Append(fullTableName);
                bool firstTime = true;
                foreach (string fieldName in entityMetadata.PrimaryKeyPropertyNames)
                {
                    var property            = entityMetadata.Properties[fieldName];
                    SqlFieldAttribute field = property.SqlField;
                    string            parameterName;
                    IDbDataParameter  param = CreateParameter(property, fieldName, out parameterName);
                    SetValueToCommandParameter(entity, getters, fieldName, param);
                    cmd.Parameters.Add(param);
                    if (firstTime)
                    {
                        commandText.Append("\nWHERE\n    ");
                        firstTime = false;
                    }
                    else
                    {
                        commandText.Append("\n    AND ");
                    }
                    commandText.Append(this.DataService.EntityLiteProvider.StartQuote + field.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote).Append(" = ").Append(parameterName);
                }
                cmd.CommandText = commandText.ToString();
                return(cmd);
            }
            catch (Exception ex)
            {
                if (entity == null)
                {
                    Log?.LogError(ex, "Error generating delete command");
                }
                else
                {
                    string primaryKey = entity.GetPrimaryKey().ToListString() ?? "'no id'";
                    string message    = string.Format(CultureInfo.InvariantCulture, "Error generating delete command for entity of type {0} with primary key: {1}", entity.GetType().Name, primaryKey);
#pragma warning disable CA2254 // Template should be a static expression
                    Log?.LogError(ex, message);
#pragma warning restore CA2254 // Template should be a static expression
                }
                throw;
            }
        }
예제 #10
0
        public void AppendInsertStatement(object entity, DbCommand cmd, StringBuilder commandText)
        {
            if (entity == null)
            {
                throw new ArgumentNullException(nameof(entity));
            }
            if (cmd == null)
            {
                throw new ArgumentNullException(nameof(cmd));
            }
            if (commandText == null)
            {
                throw new ArgumentNullException(nameof(commandText));
            }
            var    entityType                 = entity.GetType();
            var    entityMetadata             = entityType.GetEntityMetadata();
            string fullTableName              = entityMetadata.GetFullTableName(this.DataService.EntityLiteProvider.DefaultSchema, this.DataService.EntityLiteProvider.StartQuote, this.DataService.EntityLiteProvider.EndQuote);
            IPropertyGetterDictionary getters = entityType.GetPropertyGetters();
            var entityRowVersionFieldName     = DataService.SpecialFieldNames.EntityRowVersionFieldName;

            StringBuilder valuesText = new StringBuilder();

            commandText.Append("\nINSERT INTO  ").Append(fullTableName);
            bool firstTime        = true;
            var  sequenceVariable = DataService.EntityLiteProvider.SequenceVariable;
            var  startQuote       = this.DataService.EntityLiteProvider.StartQuote;
            var  parameters       = cmd.Parameters;
            var  endQuote         = this.DataService.EntityLiteProvider.EndQuote;
            var  parameterPrefix  = this.DataService.EntityLiteProvider.ParameterPrefix;

            foreach (var kv in entityMetadata.UpdatableProperties)
            {
                SqlFieldAttribute field = kv.Value.SqlField;
                //en PostgeSQL se manejan las secuencias de otra manera, como un autonumérico.
                //
                //if (field.SequenceName != null && sequenceVariable == null) continue;
                string propertyName = kv.Key;
                if (firstTime)
                {
                    commandText.Append('(');
                    valuesText.Append("\nVALUES (");
                    firstTime = false;
                }
                else
                {
                    commandText.Append(", ");
                    valuesText.Append(", ");
                }
                commandText.Append(startQuote).Append(field.BaseColumnName).Append(endQuote);

                if (propertyName == entityRowVersionFieldName)
                {
                    valuesText.Append('1');
                }
                else if (propertyName == DataService.SpecialFieldNames.DbChangeNumberFieldName)
                {
                    valuesText.Append(DataService.EntityLiteProvider.GetNextValExpression(GetDbChangeNumberFullSequenceName()));
                }
                else if (field.SequenceName != null)
                {
                    if (DataService.EntityLiteProvider.SequenceVariable != null)
                    {
                        valuesText.Append(DataService.EntityLiteProvider.SequenceVariable);
                    }
                    else
                    {
                        valuesText.Append(DataService.EntityLiteProvider.GetNextValExpression(field.SequenceName));
                    }
                }
                else
                {
                    string           parameterName;
                    IDbDataParameter param = CreateParameter(kv.Value, propertyName, out parameterName);
                    valuesText.Append(parameterName);
                    SetValueToCommandParameter(entity, getters, propertyName, param);
                    parameters.Add(param);
                }
            }
            commandText.Append(')');
            valuesText.Append(')');
            commandText.Append(valuesText.ToString());
        }
예제 #11
0
        private void GenerateUpdateWhereClauseWithPrimaryKeyAndEntityRowVersion(object entity, EntityMetadata entityMetadata, IPropertyGetterDictionary getters, DbCommand cmd, StringBuilder commandText, bool hasEntityRowVersionField)
        {
            bool firstTime = true;

            IEnumerable <string> whereFields = entityMetadata.PrimaryKeyPropertyNames;

            if (hasEntityRowVersionField)
            {
                whereFields = whereFields.Concat(new string[] { DataService.SpecialFieldNames.EntityRowVersionFieldName });
            }
            foreach (string whereField in whereFields)
            {
                var property            = entityMetadata.Properties[whereField];
                SqlFieldAttribute field = property.SqlField;
                if (string.Equals(field.ColumnName, field.BaseColumnName, StringComparison.OrdinalIgnoreCase))
                {
                    string           parameterName;
                    IDbDataParameter parameter = CreateParameter(property, whereField, out parameterName);
                    if (firstTime)
                    {
                        commandText.Append("\nWHERE\n    ");
                        firstTime = false;
                    }
                    else
                    {
                        commandText.Append("\n    AND ");
                    }
                    commandText.Append(this.DataService.EntityLiteProvider.StartQuote + field.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote)
                    .Append(" = ").Append(parameterName);


                    PropertyGetter getter;
                    if (getters.TryGetValue(whereField, out getter))
                    {
                        object parameterValue = getter(entity);
                        parameter.Value = parameterValue == null ? DBNull.Value : parameterValue;
                    }
                    cmd.Parameters.Add(parameter);
                }
            }
        }
예제 #12
0
        private void GenerateUpdateWhereClauseWithPrimaryKeyAndEntityRowVersion(object entity, EntityMetadata entityMetadata, IPropertyGetterDictionary getters, DbCommand cmd, StringBuilder commandText, bool hasEntityRowVersionField)
        {
            bool firstTime = true;

            IEnumerable<string> whereFields = entityMetadata.PrimaryKeyPropertyNames;
            if (hasEntityRowVersionField) whereFields = whereFields.Concat(new string[] { DataService.SpecialFieldNames.EntityRowVersionFieldName });
            foreach (string whereField in whereFields)
            {
                var property = entityMetadata.Properties[whereField];
                SqlFieldAttribute field = property.SqlField;
                if (string.Equals(field.ColumnName, field.BaseColumnName, StringComparison.InvariantCultureIgnoreCase))
                {
                    string parameterName = DataService.EntityLiteProvider.ParameterPrefix + whereField;
                    if (firstTime)
                    {
                        commandText.Append("\nWHERE\n    ");
                        firstTime = false;
                    }
                    else
                    {
                        commandText.Append("\n    AND ");
                    }
                    commandText.Append(this.DataService.EntityLiteProvider.StartQuote + field.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote)
                        .Append(" = ").Append(parameterName);

                    IDbDataParameter parameter = CreateParameter(property, whereField);
                    PropertyGetter getter;
                    if (getters.TryGetValue(whereField, out getter))
                    {
                        object parameterValue = getter(entity);
                        parameter.Value = parameterValue == null ? DBNull.Value : parameterValue;
                    }
                    cmd.Parameters.Add(parameter);
                }
            }
        }
예제 #13
0
 private void GenerateUpdateSetClause(object entity, IEnumerable<string> fieldsToUpdate, EntityMetadata entityMetadata, IPropertyGetterDictionary getters, DbCommand cmd, StringBuilder commandText, ref bool hasEntityRowVersionField)
 {
     bool firstTime = true;
     foreach (var propertyName in fieldsToUpdate)
     {
         PropertyMetadata propMetadata = null;
         if (!entityMetadata.UpdatableProperties.TryGetValue(propertyName, out propMetadata)) continue;
         SqlFieldAttribute field = propMetadata.SqlField;
         if (!field.IsKey
             && !string.Equals(propertyName, DataService.SpecialFieldNames.CreatedByFieldName, StringComparison.InvariantCultureIgnoreCase)
             && !string.Equals(propertyName, DataService.SpecialFieldNames.CreatedDateFieldName, StringComparison.InvariantCultureIgnoreCase)
             )
         {
             if (firstTime)
             {
                 commandText.Append(" SET\n    ");
                 firstTime = false;
             }
             else
             {
                 commandText.Append(",\n    ");
             }
             if (string.Equals(propertyName, DataService.SpecialFieldNames.EntityRowVersionFieldName, StringComparison.InvariantCultureIgnoreCase))
             {
                 hasEntityRowVersionField = true;
                 commandText.Append(this.DataService.EntityLiteProvider.StartQuote + propMetadata.SqlField.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote).Append(" = ")
                     .Append(this.DataService.EntityLiteProvider.StartQuote + propMetadata.SqlField.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote).Append(" + 1");
             }
             else
             {
                 string parameterName = DataService.EntityLiteProvider.ParameterPrefix + propertyName;
                 commandText.Append(this.DataService.EntityLiteProvider.StartQuote + field.BaseColumnName + this.DataService.EntityLiteProvider.EndQuote)
                     .Append(" = ").Append(parameterName);
                 IDbDataParameter param = CreateParameter(propMetadata, propertyName);
                 object fieldValue = getters[propertyName](entity);
                 SetValueToCommandParameter(entity, getters, propertyName, param);
                 cmd.Parameters.Add(param);
             }
         }
     }
 }
예제 #14
0
 private static void SetValueToCommandParameter(object entity, IPropertyGetterDictionary getters, string propertyName, IDbDataParameter param)
 {
     var getter = getters[propertyName];
     if (getter == null) return;
     object fieldValue = getter(entity);
     var nullable = fieldValue as INullable;
     if (nullable != null && nullable.IsNull)
     {
         param.Value = DBNull.Value;
     }
     else
     {
         if (fieldValue != null && (param.DbType == DbType.String || param.DbType == DbType.AnsiString) && !(fieldValue is string))
         {
             var convertible = fieldValue as IConvertible;
             if (convertible != null)
             {
                 fieldValue = convertible.ToString(CultureInfo.InvariantCulture);
             }
             else
             {
                 fieldValue = fieldValue.ToString();
             }
         }
         param.Value = fieldValue ?? DBNull.Value;
     }
 }