/// <summary> /// Creates a parameter from object by mapping the property from the target entity type. /// </summary> /// <param name="command">The command object to be used.</param> /// <param name="param">The object to be used when creating the parameters.</param> /// <param name="propertiesToSkip">The list of the properties to be skipped.</param> internal static void CreateParameters(this IDbCommand command, object param, IEnumerable <string> propertiesToSkip) { // Check for presence if (param == null) { return; } // Supporting the IDictionary<string, object> if (param is ExpandoObject || param is IDictionary <string, object> ) { CreateParameters(command, (IDictionary <string, object>)param, propertiesToSkip); } // Supporting the QueryField else if (param is QueryField) { CreateParameters(command, (QueryField)param, propertiesToSkip); } // Supporting the IEnumerable<QueryField> else if (param is IEnumerable <QueryField> ) { CreateParameters(command, (IEnumerable <QueryField>)param, propertiesToSkip); } // Supporting the QueryGroup else if (param is QueryGroup) { CreateParameters(command, (QueryGroup)param, propertiesToSkip); } // Otherwise, iterate the properties else { var type = param.GetType(); // Check the validity of the type if (type.IsGenericType && type.GetGenericTypeDefinition() == m_dictionaryType) { throw new InvalidParameterException("The supported type of dictionary object must be of type IDictionary<string, object>."); } // Variables for properties var properties = (IEnumerable <ClassProperty>)null; // Add this check for performance if (type.IsGenericType == true) { properties = type.GetClassProperties(); } else { properties = PropertyCache.Get(type); } // Skip some properties if (propertiesToSkip != null) { properties = properties? .Where(p => propertiesToSkip?.Contains(p.PropertyInfo.Name, StringComparer.OrdinalIgnoreCase) == false); } // Iterate the properties foreach (var property in properties) { // Get the property vaues var name = property.GetMappedName(); var value = property.PropertyInfo.GetValue(param); // Get property db type var dbType = property.GetDbType(); // Ensure mapping based on the value type if (dbType == null) { dbType = TypeMapper.Get(value?.GetType().GetUnderlyingType()); } // Check for specialized if (dbType == null) { var propertyType = property.PropertyInfo.PropertyType.GetUnderlyingType(); if (propertyType?.IsEnum == true) { dbType = DbType.String; } else if (propertyType == m_bytesType) { dbType = DbType.Binary; } } // Add the new parameter command.Parameters.Add(command.CreateParameter(name, value, dbType)); } } }
/// <summary> /// Set the <see cref="IDbCommand"/> object existing <see cref="IDbDataParameter"/> values. /// </summary> /// <param name="command">The command object to be used.</param> /// <param name="param">The instance of where the parameter values will be set.</param> /// <param name="propertiesToSkip">The list of the properties to be skipped.</param> /// <param name="resetOthers">True to reset the other parameter object. This will ignore the skipped properties.</param> internal static void SetParameters(this IDbCommand command, object param, IEnumerable <string> propertiesToSkip, bool resetOthers) { // Do nothing if there is no parameter if (command.Parameters.Count == 0) { return; } // Check for presence if (param == null) { foreach (var parameter in command.Parameters.OfType <DbParameter>()) { parameter.Value = DBNull.Value; parameter.ResetDbType(); } } // Supporting the IDictionary<string, object> else if (param is ExpandoObject || param is IDictionary <string, object> ) { SetParameters(command, (IDictionary <string, object>)param, propertiesToSkip, resetOthers); } // Supporting the QueryField else if (param is QueryField) { SetParameters(command, (QueryField)param, propertiesToSkip, resetOthers); } // Supporting the IEnumerable<QueryField> else if (param is IEnumerable <QueryField> ) { SetParameters(command, (IEnumerable <QueryField>)param, propertiesToSkip, resetOthers); } // Supporting the QueryGroup else if (param is QueryGroup) { SetParameters(command, (QueryGroup)param, propertiesToSkip, resetOthers); } // Otherwise, iterate the properties else { var type = param.GetType(); // Check the validity of the type if (type.IsGenericType && type.GetGenericTypeDefinition() == m_dictionaryType) { throw new InvalidParameterException("The supported type of dictionary object must be of type IDictionary<string, object>."); } // variables for properties var properties = (IEnumerable <ClassProperty>)null; // Add this check for performance if (propertiesToSkip == null) { properties = PropertyCache.Get(type); } else { properties = PropertyCache.Get(type) .Where(p => propertiesToSkip?.Contains(p.PropertyInfo.Name, StringComparer.OrdinalIgnoreCase) == false); } // Ensure there are properties if (resetOthers == true && properties.Any() != true) { SetParameters(command, (object)null, propertiesToSkip, true); } else { var parameters = command.Parameters.OfType <DbParameter>(); var missingParameters = (IList <DbParameter>)null; // Iterate the parameter instead foreach (var parameter in parameters) { var property = properties.FirstOrDefault(p => string.Equals(p.GetMappedName(), parameter.ParameterName, StringComparison.OrdinalIgnoreCase)); // Skip if null if (property == null) { // Add to missing properties if allowed to if (resetOthers == true) { if (missingParameters == null) { missingParameters = new List <DbParameter>(); } missingParameters.Add(parameter); } // Continue to next continue; } // Get the property values var value = property.PropertyInfo.GetValue(param); var dbType = property.GetDbType() ?? TypeMapper.Get(property.PropertyInfo.PropertyType.GetUnderlyingType()); // Ensure the type mapping if (dbType == null) { if (value == null && property.PropertyInfo.PropertyType == m_bytesType) { dbType = DbType.Binary; } } // Set the parameter parameter.Value = value; if (dbType != null) { parameter.DbType = dbType.Value; } } // If there is any (then set to null) if (resetOthers == true && missingParameters?.Count != 0) { foreach (var parameter in missingParameters) { parameter.Value = DBNull.Value; parameter.ResetDbType(); } } } } }
/// <summary> /// Merges an object into an instance of <see cref="QueryGroup"/> object. /// </summary> /// <typeparam name="TEntity">The type of the object.</typeparam> /// <param name="obj">The object to be merged.</param> /// <param name="queryGroup">The <see cref="QueryGroup"/> object to be merged.</param> /// <returns>An instance of converted dynamic object.</returns> internal static object Merge <TEntity>(this TEntity obj, QueryGroup queryGroup) where TEntity : class { return(Merge(obj, PropertyCache.Get <TEntity>().Select(p => p.PropertyInfo), queryGroup)); }
public void Start() { var host = new Host(); var lineHit = new LineHit(); var propCache = new PropertyCache(); var shapeSerializer = new ShapeSerializer(propCache); var sceneStore = new JsonSceneStore(); var rotateParam = new RotateParam { Angle = 0 }; var rotateView = new IntInputView { DataContext = new RotateViewModel(rotateParam) }; var thiknessParam = new ThiknessParam { Thikness = 5 }; var thiknessView = new IntInputView { DataContext = new ThiknessViewModel(thiknessParam) }; var colorParam = new ColorParam { Color = Colors.Black }; var colorView = new ColorView { DataContext = new ColorViewModel <IShapeObject>(colorParam) }; var fillParam = new FillParam { Color = Colors.Transparent }; var fillView = new ColorView { DataContext = new ColorViewModel <IFillObject>(fillParam) }; var vm = new HostViewModel( host.Canvas, new List <ShapeToolParam> { new ShapeToolParam("Поворот", rotateView, rotateParam), new ShapeToolParam("Толщина", thiknessView, thiknessParam), new ShapeToolParam("Цвет", colorView, colorParam), new ShapeToolParam("Заливка", fillView, fillParam), }, sceneStore, new ShapeTool(0, LoadImage("pack://application:,,,/Painter;component/Resources/Images/line.png"), new PolyLineCreator(0, 50, Brushes.Black, 10, lineHit, shapeSerializer)), new ShapeTool(1, LoadImage("pack://application:,,,/Painter;component/Resources/Images/rectangle.png"), new RectangleCreator(1, 50, 50, Brushes.Black, 10, Brushes.Transparent, lineHit, shapeSerializer)) ); host.DataContext = vm; App.Current.MainWindow = host; host.Show(); }
/// <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; } // Validate, make sure to only have the proper operation if (queryField.Operation != Operation.Equal) { throw new InvalidOperationException($"Operation must only be '{nameof(Operation.Equal)}' when calling the 'Execute' methods."); } // 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 == bytesType) { dbType = DbType.Binary; } } } #endregion // Create the parameter command.Parameters.Add(command.CreateParameter(queryField.Parameter.Name, value, dbType)); }
void AddParameter(Enum property, PropertyCache cache, object value) { container.AddParameter(new CustomParameter(GetParameterName(property, cache), value?.ToString())); }
/// <summary> /// /// </summary> /// <param name="paramType"></param> /// <param name="entityType"></param> /// <param name="dbFields"></param> /// <returns></returns> internal static Action <DbCommand, object> GetPlainTypeToDbParametersCompiledFunction(Type paramType, Type entityType, IEnumerable <DbField> dbFields = null) { var commandParameterExpression = Expression.Parameter(StaticType.DbCommand, "command"); var entityParameterExpression = Expression.Parameter(StaticType.Object, "entity"); var entityExpression = ConvertExpressionToTypeExpression(entityParameterExpression, paramType); var methodInfo = GetDbCommandCreateParameterMethod(); var callExpressions = new List <Expression>(); var paramProperties = PropertyCache.Get(paramType); var entityProperties = PropertyCache.Get(entityType); // Iterate foreach (var paramProperty in paramProperties) { // Ensure it matching any params var entityProperty = entityProperties?.FirstOrDefault(e => string.Equals(e.GetMappedName(), paramProperty.GetMappedName(), StringComparison.OrdinalIgnoreCase) || string.Equals(e.PropertyInfo.Name, paramProperty.PropertyInfo.Name, StringComparison.OrdinalIgnoreCase)); // Variables var dbField = dbFields?.FirstOrDefault(df => string.Equals(df.Name, paramProperty.GetMappedName(), StringComparison.OrdinalIgnoreCase)); var valueExpression = (Expression)Expression.Property(entityExpression, paramProperty.PropertyInfo); var valueType = (entityProperty ?? paramProperty).PropertyInfo.PropertyType.GetUnderlyingType(); // PropertyHandler var handlerSetTuple = ConvertExpressionToPropertyHandlerSetExpressionTuple(valueExpression, paramProperty, valueType); if (handlerSetTuple.handlerSetReturnType != null) { valueExpression = handlerSetTuple.convertedExpression; valueType = handlerSetTuple.handlerSetReturnType; } // Automatic if (Converter.ConversionType == ConversionType.Automatic && dbField?.Type != null) { valueType = dbField.Type.GetUnderlyingType(); valueExpression = ConvertExpressionWithAutomaticConversion(valueExpression, valueType); } // DbType var dbType = (paramProperty == null ? null : TypeMapCache.Get(paramProperty.GetDeclaringType(), paramProperty.PropertyInfo)) ?? (entityProperty == null ? null : TypeMapCache.Get(entityProperty.GetDeclaringType(), entityProperty.PropertyInfo)); if (dbType == null && (valueType ??= dbField?.Type.GetUnderlyingType()) != null) { dbType = valueType.GetDbType() ?? // type level, use TypeMapCache new ClientTypeToDbTypeResolver().Resolve(valueType) ?? // type level, primitive mapping (valueType.IsEnum ? Converter.EnumDefaultDatabaseType : null); // use Converter.EnumDefaultDatabaseType } var dbTypeExpression = dbType == null?GetNullableTypeExpression(StaticType.DbType) : ConvertExpressionToNullableExpression(Expression.Constant(dbType), StaticType.DbType); // DbCommandExtension.CreateParameter var expression = Expression.Call(methodInfo, new Expression[] { commandParameterExpression, Expression.Constant(paramProperty.GetMappedName()), ConvertExpressionToTypeExpression(valueExpression, StaticType.Object), dbTypeExpression }); // DbCommand.Parameters.Add var parametersExpression = Expression.Property(commandParameterExpression, "Parameters"); var addExpression = Expression.Call(parametersExpression, GetDbParameterCollectionAddMethod(), expression); // Add callExpressions.Add(addExpression); } // Return return(Expression .Lambda <Action <DbCommand, object> >(Expression.Block(callExpressions), commandParameterExpression, entityParameterExpression) .CompileFast()); }
/// <summary> /// Returns the property of the type based on the mappings equality. /// </summary> /// <param name="type">The current type.</param> /// <param name="mappedName">The name of the property mapping.</param> /// <returns>The instance of <see cref="ClassProperty"/>.</returns> internal static ClassProperty GetMappedProperty(this Type type, string mappedName) => PropertyCache.Get(type)?.FirstOrDefault(p => string.Equals(p.GetMappedName(), mappedName, StringComparison.OrdinalIgnoreCase));
/// <summary> /// Executes the query. /// </summary> /// <typeparam name="T">The type to return</typeparam> /// <param name="queryParameters">Parameters to pass to the statement.</param> /// <param name="propertyCache">An object used for caching information about the typed object.</param> /// <param name="transaction">An active database transaction used for rollbacks.</param> /// <returns> /// The number of rows affescted. /// </returns> public virtual async Task <int> ExecuteAsync <T>(object queryParameters = null, PropertyCache propertyCache = null, IDbTransaction transaction = null) where T : class { string sql = GenerateStatement <T>(propertyCache); if (UseIdentity(queryParameters)) { var result = await QueryAsync <int>(sql, queryParameters, transaction : transaction); return(result.First()); } else { return(await ExecuteNonQueryAsync(sql, queryParameters, transaction : transaction)); } }
protected virtual string GetParameterName(Enum property, PropertyCache cache) { return(ObjectPropertyParser.GetObjectPropertyNameViaCache(property, cache)); }
/// <summary> /// Uses reflection to determine information about the typed class. /// </summary> /// <typeparam name="T">The type to return</typeparam> /// <param name="propertyCache">An object used for caching information about the typed object.</param> private void ReflectType <T>(PropertyCache propertyCache) where T : class { propNames = ReflectionHelper.ReflectProperties <T>(propertyCache, new[] { typeof(IdentityAttribute), typeof(InsertIgnoreAttribute) }); keyField = ReflectionHelper.GetIdentityField <T>(propertyCache); }
/// <summary> /// Generates the sql statement to be executed. /// </summary> /// <typeparam name="T">The type to return</typeparam> /// <param name="propertyCache">An object used for caching information about the typed object.</param> /// <returns> /// The completed sql statement to be executed. /// </returns> public string GenerateStatement <T>(PropertyCache propertyCache) where T : class { ReflectType <T>(propertyCache); return(GenerateStatement()); }
/// <summary> /// Converts all properties of the type into an array of <see cref="Field"/> objects. /// </summary> /// <param name="type">The current type.</param> /// <returns>A list of <see cref="Field"/> objects.</returns> internal static IEnumerable <Field> AsFields(this Type type) => PropertyCache.Get(type).AsFields();
private static PropertyCache GetCachedProperties(System.Type type) { RuntimeHelpers.RunClassConstructor(type.TypeHandle); PropertyCache propertyCache; if (!ModelProperty.cachedProperties.TryGetValue(type, out propertyCache)) { propertyCache = new PropertyCache(); ModelProperty.cachedProperties.Add(type, propertyCache); HashSet<ModelProperty> allProperties = new HashSet<ModelProperty>(); Dictionary<string, ModelProperty> propertyList; if (ModelProperty.properties.TryGetValue(type, out propertyList)) { propertyCache.DeclaredProperties.AddRange(propertyList.Values); allProperties.UnionWith(propertyList.Values); foreach (var prop in propertyList.Values) { if (!propertyCache.Properties.Any(p => p.Name == prop.Name)) { propertyCache.Properties.Add(prop); } } } foreach (var super in type.GetInterfaces()) { var superProperties = ModelProperty.GetCachedProperties(super).AllProperties; allProperties.UnionWith(superProperties); foreach (var prop in superProperties) { if (!propertyCache.Properties.Any(p => p.Name == prop.Name)) { propertyCache.Properties.Add(prop); } } } propertyCache.AllProperties.AddRange(allProperties); } return propertyCache; }
/// <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 = 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 == bytesType) { dbType = DbType.Binary; } } #endregion } } // Add the parameter command.Parameters.Add(command.CreateParameter(kvp.Key, value, dbType)); } }
static ReflectionCache() { propertyCache = new PropertyCache(); }
public ShapeSerializer(PropertyCache propertyCache) { this.propertyCache = propertyCache; }