Пример #1
0
        /// <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));
                }
            }
        }
Пример #2
0
        /// <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();
                        }
                    }
                }
            }
        }
Пример #3
0
 /// <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));
 }
Пример #4
0
        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();
        }
Пример #5
0
        /// <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));
        }
Пример #6
0
 void AddParameter(Enum property, PropertyCache cache, object value)
 {
     container.AddParameter(new CustomParameter(GetParameterName(property, cache), value?.ToString()));
 }
Пример #7
0
        /// <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());
        }
Пример #8
0
 /// <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));
Пример #9
0
        /// <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));
            }
        }
Пример #10
0
 protected virtual string GetParameterName(Enum property, PropertyCache cache)
 {
     return(ObjectPropertyParser.GetObjectPropertyNameViaCache(property, cache));
 }
Пример #11
0
 /// <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);
 }
Пример #12
0
 /// <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());
 }
Пример #13
0
 /// <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();
Пример #14
0
 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;
 }
Пример #15
0
        /// <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));
            }
        }
Пример #16
0
 static ReflectionCache()
 {
     propertyCache = new PropertyCache();
 }
Пример #17
0
 public ShapeSerializer(PropertyCache propertyCache)
 {
     this.propertyCache = propertyCache;
 }