private static Func <object, object> GetConverter(PocoColumn pc, Type srcType, Type dstType)
        {
            if (srcType == dstType)
            {
                return(null);
            }

            // Standard DateTime->Utc mapper
            if (pc != null && pc.ForceToUtc && srcType == ColumnType.DateTimeType && (dstType == ColumnType.DateTimeType || dstType == ColumnType.NullDateTimeType))
            {
                return(delegate(object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); });
            }

            // unwrap nullable types
            Type underlyingDstType = Nullable.GetUnderlyingType(dstType);

            if (underlyingDstType != null)
            {
                dstType = underlyingDstType;
            }

            // Forced type conversion including integral types -> enum
            if (dstType.IsEnum && IsIntegralType(srcType))
            {
                var backingDstType = Enum.GetUnderlyingType(dstType);
                if (underlyingDstType != null)
                {
                    // if dstType is Nullable<Enum>, convert to enum value
                    return(delegate(object src) { return Enum.ToObject(dstType, src); });
                }
                else if (srcType != backingDstType)
                {
                    return(delegate(object src) { return Convert.ChangeType(src, backingDstType, null); });
                }
            }
            else if (!dstType.IsAssignableFrom(srcType))
            {
                if (dstType.IsEnum && srcType == ColumnType.StringType)
                {
                    return(delegate(object src) { return EnumMapper.EnumFromString(dstType, (string)src); });
                }
                else if (dstType == ColumnType.GuidType && srcType == ColumnType.StringType)
                {
                    return(delegate(object src) { return Guid.Parse((string)src); });
                }
                else
                {
                    return(delegate(object src) { return Convert.ChangeType(src, dstType, null); });
                }
            }

            return(null);
        }
        private PocoColumn FromProperty(PropertyInfo pi)
        {
            if (pi.CanRead == false || pi.CanWrite == false)
            {
                return(null);
            }
            if (ColumnType.IsAllowType(pi.PropertyType) == false)
            {
                return(null);
            }
            var a = pi.GetCustomAttributes(typeof(IgnoreAttribute), true);

            if (a.Length > 0)
            {
                return(null);
            }

            var ci = new PocoColumn();

            ci.PropertyName = pi.Name;
            var colAttrs = pi.GetCustomAttributes(typeof(ColumnAttribute), true);

            if (colAttrs.Length > 0)
            {
                var colattr = (ColumnAttribute)colAttrs[0];

                ci.ColumnName = colattr.Name == null ? pi.Name : colattr.Name;
                ci.ForceToUtc = colattr.ForceToUtc;
                if ((colattr as ResultColumnAttribute) != null)
                {
                    ci.ResultColumn = true;
                    ci.ResultSql    = (colattr as ResultColumnAttribute).Definition;
                }
            }
            else
            {
                ci.ColumnName   = pi.Name;
                ci.ForceToUtc   = false;
                ci.ResultColumn = false;
            }
            ci.PropertyInfo = pi;
            return(ci);
        }