/// <summary> /// Creates a command parameter from the <see cref="QueryField"/> object. /// </summary> /// <param name="command">The command object to be used.</param> /// <param name="queryField">The value of <see cref="QueryField"/> object.</param> /// <param name="propertiesToSkip">The list of the properties to be skipped.</param> /// <param name="entityType">The type of the data entity.</param> internal static void CreateParameters(this IDbCommand command, QueryField queryField, IEnumerable <string> propertiesToSkip, Type entityType) { // Exclude those to be skipped if (propertiesToSkip?.Contains(queryField.Field.Name, StringComparer.OrdinalIgnoreCase) == true) { return; } // Get the values var value = queryField.Parameter.Value; var valueType = value?.GetType()?.GetUnderlyingType(); var dbType = (DbType?)null; #region PropertyHandler // Check the property handler var typeHandler = PropertyHandlerCache.Get <object>(valueType); if (typeHandler != null) { var classProperty = (ClassProperty)null; var setMethod = typeHandler.GetType().GetMethod("Set"); var returnType = setMethod.ReturnType; if (entityType != null) { classProperty = PropertyCache.Get(entityType, queryField.Field); } dbType = clientTypeToDbTypeResolver.Resolve(returnType); value = setMethod.Invoke(typeHandler, new[] { value, classProperty }); } #endregion #region DbType else { dbType = TypeMapCache.Get(valueType); // Check for the specialized types if (dbType == null) { if (valueType?.IsEnum == true) { dbType = DbType.String; } else if (valueType == StaticType.ByteArray) { dbType = DbType.Binary; } } } #endregion // Create the parameter command.Parameters.Add(command.CreateParameter(queryField.Parameter.Name, value, dbType)); }
public void TestPropertyHandlerCacheWithoutMapping() { // Act var result = PropertyHandlerCache.Get <PropertyHandlerCacheTest, StringPropertyHandler>(); // Assert Assert.IsNull(result); }
/// <summary> /// /// </summary> /// <param name="classProperty"></param> /// <param name="targetType"></param> /// <returns></returns> private static object GetProperyHandler(ClassProperty classProperty, Type targetType) { var propertyHandler = classProperty?.GetPropertyHandler(); if (propertyHandler == null && targetType != null) { propertyHandler = PropertyHandlerCache.Get <object>(targetType); } return(propertyHandler); }
public void TestPropertyHandlerCacheWithMapping() { // Setup var stringPropertyHandler = new StringPropertyHandler(); PropertyHandlerMapper.Add <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(stringPropertyHandler); // Act var result = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(); var expected = stringPropertyHandler; // Assert Assert.AreEqual(expected, result); }
public void TestPropertyHandlerCachePropertyMappingViaExpressionWithMapAttribute() { // Act var actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, TextPropertyHandler>(e => e.PropertyString); // Assert Assert.IsNotNull(actual); // Act (Existing) actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, TextPropertyHandler>(e => e.PropertyString); // Assert Assert.IsNotNull(actual); }
public void TestPropertyHandlerCachePropertyMappingViaExpression() { // Setup var stringPropertyHandler = new StringPropertyHandler(); PropertyHandlerMapper.Add <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(e => e.ColumnString, stringPropertyHandler); // Act var actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(e => e.ColumnString); var expected = stringPropertyHandler; // Assert Assert.AreEqual(expected, actual); }
public void TestPropertyHandlerCachePropertyMappingViaField() { // Setup var field = new Field("ColumnString"); var stringPropertyHandler = new StringPropertyHandler(); PropertyHandlerMapper.Add <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(field, stringPropertyHandler); // Act var actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(field); var expected = stringPropertyHandler; // Assert Assert.AreEqual(expected, actual); }
public void TestPropertyHandlerCachePropertyMappingViaPropertyName() { // Setup var propertyName = "ColumnString"; var stringPropertyHandler = new StringPropertyHandler(); PropertyHandlerMapper.Add <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(propertyName, stringPropertyHandler); // Act var actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, StringPropertyHandler>(propertyName); var expected = stringPropertyHandler; // Assert Assert.AreEqual(expected, actual); }
public void TestPropertyHandlerCachePropertyMappingViaFieldWithMapAttribute() { // Setup var field = new Field("PropertyString"); // Act var actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, TextPropertyHandler>(field); // Assert Assert.IsNotNull(actual); // Act (Existing) actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, TextPropertyHandler>(field); // Assert Assert.IsNotNull(actual); }
public void TestPropertyHandlerCachePropertyMappingViaPropertyNameWithMapAttribute() { // Setup var propertyName = "PropertyString"; // Act var actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, TextPropertyHandler>(propertyName); // Assert Assert.IsNotNull(actual); // Act (Existing) actual = PropertyHandlerCache.Get <PropertyTypeHandlerCacheTestClass, TextPropertyHandler>(propertyName); // Assert Assert.IsNotNull(actual); }
public void TestPropertyHandlerMapperPropertyMappingViaExpressionWithPropertyHandlerAttribute() { // Setup var stringPropertyHandler = new StringPropertyHandler(); PropertyHandlerMapper.Add <PropertyHandlerMapperTestClass, StringPropertyHandler>(e => e.PropertyString, stringPropertyHandler); // Act var actual = PropertyHandlerMapper.Get <PropertyHandlerMapperTestClass, StringPropertyHandler>(e => e.PropertyString); // Assert Assert.IsNotNull(actual); // Act var textHandler = PropertyHandlerCache.Get <PropertyHandlerMapperTestClass, TextPropertyHandler>(e => e.PropertyString); // Assert Assert.IsNotNull(textHandler); }
public void TestPropertyHandlerMapperPropertyMappingViaFieldWithPropertyHandlerAttribute() { // Setup var stringPropertyHandler = new StringPropertyHandler(); var field = new Field("PropertyString"); PropertyHandlerMapper.Add <PropertyHandlerMapperTestClass, StringPropertyHandler>(field, stringPropertyHandler); // Act var actual = PropertyHandlerMapper.Get <PropertyHandlerMapperTestClass, StringPropertyHandler>(field); // Assert Assert.IsNotNull(actual); // Act var textHandler = PropertyHandlerCache.Get <PropertyHandlerMapperTestClass, TextPropertyHandler>(field); // Assert Assert.IsNotNull(textHandler); }
public void TestPropertyHandlerMapperPropertyMappingViaPropertyNameWithPropertyHandlerAttribute() { // Setup var stringPropertyHandler = new StringPropertyHandler(); var propertyName = "PropertyString"; PropertyHandlerMapper.Add <PropertyHandlerMapperTestClass, StringPropertyHandler>(propertyName, stringPropertyHandler); // Act var actual = PropertyHandlerMapper.Get <PropertyHandlerMapperTestClass, StringPropertyHandler>(propertyName); // Assert Assert.IsNotNull(actual); // Act var textHandler = PropertyHandlerCache.Get <PropertyHandlerMapperTestClass, TextPropertyHandler>(propertyName); // Assert Assert.IsNotNull(textHandler); }
/// <summary> /// Create Parameter, the process will handle value conversion and type conversion. /// </summary> /// <param name="command">The command object to be used.</param> /// <param name="name">Entity property's name.</param> /// <param name="value">Entity property's value, maybe null.</param> /// <param name="classProperty"> /// The entity's class property information. <br /> /// If the parameter is a dictionary, it will be null, otherwise it will not be null. /// </param> /// <param name="dbField"> /// Used to get the actual field type information of the database to determine whether automatic type conversion is required. <br /> /// When the tableName is assigned, it will be based on the database field information obtained by the tableName, so this parameter will be null in most cases. /// </param> /// <param name="parameterDirection">The direction of the parameter.</param> /// <param name="fallbackType">Used when none of the above parameters can determine the value of Parameter.DbType.</param> /// <returns>An instance of the newly created parameter object.</returns> private static IDbDataParameter CreateParameter(IDbCommand command, string name, object value, ClassProperty classProperty, DbField dbField, ParameterDirection?parameterDirection, Type fallbackType) { /* * In some cases, the value type and the classProperty type will be inconsistent, Therefore, the type gives priority to value. * ex: in RepoDb.MySql.IntegrationTests.TestMySqlConnectionForQueryForMySqlMapAttribute * entity AttributeTable.Id = int * database completetable.Id = bigint(20) AUTO_INCREMENT * value id in connection.Query<AttributeTable>(id) is from connection.Insert<AttributeTable>(table) = ulong */ var valueType = (value?.GetType() ?? classProperty?.PropertyInfo.PropertyType).GetUnderlyingType(); /* * Try to get the propertyHandler, the order of the source of resolve is classProperty and valueType. * If the propertyHandler exists, the value and DbType are re-determined by the propertyHandler. */ var propertyHandler = classProperty?.GetPropertyHandler() ?? (valueType == null ? null : PropertyHandlerCache.Get <object>(valueType)); if (propertyHandler != null) { var propertyHandlerSetMethod = propertyHandler.GetType().GetMethod("Set"); value = propertyHandlerSetMethod.Invoke(propertyHandler, new[] { value, classProperty }); valueType = propertyHandlerSetMethod.ReturnType.GetUnderlyingType(); } /* * When the database field information exists and the field type definition is found to be different from the valueType, * if automatic type conversion is activated at this time, it will be processed. */ if (valueType != null && dbField != null && IsAutomaticConversion(dbField)) { var dbFieldType = dbField.Type.GetUnderlyingType(); if (dbFieldType != valueType) { if (value != null) { value = AutomaticConvert(value, valueType, dbFieldType); } valueType = dbFieldType; } } /* * Set DbType as much as possible, to avoid parameter misjudgment when Value is null. * order: * 1. attribute level, TypeMapAttribute define on class's property * 2. property level, assigned by TypeMapper.Add(entityType, property, dbType, ...) * 3. type level, use TypeMapCache, assigned by TypeMapper.Add(type, dbType, ...), not included Primitive mapping. * 4. type level, primitive mapping, included special type. ex: byte[] ...etc. * 5. if isEnum, use Converter.EnumDefaultDatabaseType. */ // if classProperty exists, try get dbType from attribute level or property level, // The reason for not using classProperty.GetDbType() is to avoid getting the type level mapping. var dbType = classProperty?.GetDbType(); if (dbType == null && (valueType ??= dbField?.Type.GetUnderlyingType() ?? fallbackType) != null) { dbType = valueType.GetDbType() ?? // type level, use TypeMapCache clientTypeToDbTypeResolver.Resolve(valueType) ?? // type level, primitive mapping (dbField?.Type != null ? clientTypeToDbTypeResolver.Resolve(dbField?.Type) : null); // fallback to the database type } if (dbType == null && valueType.IsEnum) { dbType = Converter.EnumDefaultDatabaseType; // use Converter.EnumDefaultDatabaseType } /* * Return the parameter */ return(command.CreateParameter(name, value, dbType, parameterDirection)); }
/// <summary> /// Create the command parameters from the <see cref="IDictionary{TKey, TValue}"/> object. /// </summary> /// <param name="command">The command object to be used.</param> /// <param name="dictionary">The parameters from the <see cref="Dictionary{TKey, TValue}"/> object.</param> /// <param name="propertiesToSkip">The list of the properties to be skipped.</param> /// <param name="entityType">The type of the data entity.</param> internal static void CreateParameters(this IDbCommand command, IDictionary <string, object> dictionary, IEnumerable <string> propertiesToSkip, Type entityType) { // Variables needed var kvps = dictionary.Where(kvp => propertiesToSkip?.Contains(kvp.Key, StringComparer.OrdinalIgnoreCase) != true); // Iterate the key value pairs foreach (var kvp in kvps) { var dbType = (DbType?)null; var value = kvp.Value; var valueType = (Type)null; var declaringType = entityType; var property = (PropertyInfo)null; // Cast the proper object and identify the properties if (kvp.Value is CommandParameter) { var commandParameter = (CommandParameter)kvp.Value; // Get the property and value property = commandParameter.MappedToType.GetProperty(kvp.Key); declaringType = commandParameter.MappedToType ?? property.DeclaringType; value = commandParameter.Value; // Set the value type valueType = value?.GetType()?.GetUnderlyingType(); } else { // In this area, it could be a 'dynamic' object valueType = kvp.Value?.GetType()?.GetUnderlyingType(); } // Get the property-level mapping if (property != null) { #region PropertyHandler // Check the property handler var propertyHandler = PropertyHandlerCache.Get <object>(declaringType, property); if (propertyHandler != null) { var setMethod = propertyHandler.GetType().GetMethod("Set"); var returnType = setMethod.ReturnType; var classProperty = PropertyCache.Get(declaringType, property); dbType = m_clientTypeToDbTypeResolver.Resolve(returnType); value = setMethod.Invoke(propertyHandler, new[] { value, classProperty }); } #endregion else { #region DbType dbType = TypeMapCache.Get(property.DeclaringType, property); // Check for the specialized types if (dbType == null) { if (valueType?.IsEnum == true) { dbType = DbType.String; } else if (valueType == m_bytesType) { dbType = DbType.Binary; } } #endregion } } // Add the parameter command.Parameters.Add(command.CreateParameter(kvp.Key, value, dbType)); } }