Ejemplo n.º 1
0
        public T Bind <T>(object[] rowValues, string pattern = null)
        {
            var type = typeof(T);

            if (TypesOverwrite.TryGetValue(type, out var rType))
            {
                type = rType;
            }

            if (ColumnIndex.Count != rowValues.Length)
            {
                throw new ArgumentException("The row values length is different from the expected.");
            }

            if (type == typeof(DictionaryObject))
            {
                var dicData = ColumnIndex.Select((c, rValues) => new KeyValuePair <string, object>(c.Key, rValues[c.Value]), rowValues).ToDictionary();
                return((T)(object)new DictionaryObject(dicData));
            }

            var entityInfo = PrepareEntity(type);
            var entity     = (T)entityInfo.Activator();

            foreach (var prop in entityInfo.Properties)
            {
                var propName = prop.Name;
                if (pattern.IsNotNullOrEmpty())
                {
                    propName = pattern.Replace("%", propName);
                }

                if (!ColumnIndex.ContainsKey(propName))
                {
                    continue;
                }

                var idx = ColumnIndex[propName];
                if (idx >= rowValues.Length || idx < 0)
                {
                    Core.Log.Warning($"The value for the property: {propName} on the entity: {type.Name} could'nt be found on index: {idx}. Please check if there are duplicate column names in the query.");
                    continue;
                }
                var value            = rowValues[idx];
                var valueType        = value?.GetType();
                var propertyType     = prop.PropertyUnderlayingType;
                var propertyTypeInfo = prop.PropertyUnderlayingTypeInfo;
                var defaultValue     = prop.PropertyTypeInfo.IsValueType ? Activator.CreateInstance(prop.PropertyType) : null;

                if (value == null)
                {
                    prop.SetValue(entity, defaultValue);
                }
                else if (propertyType == valueType)
                {
                    prop.SetValue(entity, value);
                }
                else
                {
                    var result = defaultValue;

                    if (propertyType == typeof(Guid) && valueType == typeof(string))
                    {
                        result = new Guid((string)value);
                    }
                    else if (propertyTypeInfo.IsEnum &&
                             (valueType == typeof(int) || valueType == typeof(long) || valueType == typeof(string) || valueType == typeof(byte) || valueType == typeof(short)))
                    {
                        result = Enum.Parse(propertyType, value.ToString());
                    }
                    else if (ValueConverter != null && ValueConverter.Convert(value, valueType, prop.PropertyType, out var valueConverterResult))
                    {
                        result = valueConverterResult;
                    }
                    else if (!InvalidCastList.Any((i, vTuple) => i.ValueType == vTuple.valueType && i.PropertyType == vTuple.propertyType, (valueType, propertyType)))
                    {
                        try
                        {
                            result = Convert.ChangeType(value, propertyType);
                        }
                        catch (InvalidCastException exCast)
                        {
                            Core.Log.Write(exCast);
                            InvalidCastList.Add(new InvalidCast(valueType, propertyType));
                        }
                        catch (Exception ex)
                        {
                            Core.Log.Write(ex);
                        }
                    }

                    prop.SetValue(entity, result);
                }
            }
            return(entity);
        }