示例#1
0
        internal static Type GetClrType(this Type type)
        {
            Type clrType;
            QueryTalkException exception;
            var match = Mapping.CheckClrCompliance(type, out clrType, out exception);

            if (match != Mapping.ClrTypeMatch.ClrMatch)
            {
                return(null);
            }

            return(clrType);
        }
示例#2
0
        internal Variable(long ordinal, string name, Type type, IdentifierType variableType)
            : this(ordinal, name, variableType)
        {
            Type clrType;
            var  typeMatch = Mapping.CheckClrCompliance(type, out clrType, out _exception);

            if (typeMatch != Mapping.ClrTypeMatch.ClrMatch)
            {
                return;
            }

            DataType = Mapping.ClrMapping[clrType].DefaultDataType;
        }
示例#3
0
        internal static string BuildUnchecked(object value, out QueryTalkException exception)
        {
            exception = null;

            if (value == null)
            {
                return(Text.Null);
            }

            Type type = value.GetType();

            if (type == typeof(DBNull) || type == typeof(System.Object))
            {
                return(Text.Null);
            }

            if (type == typeof(View))
            {
                return(((View)value).Sql);
            }

            if (type == typeof(Value))
            {
                var data = (Value)value;

                if (data == Designer.Null)
                {
                    return(Text.Null);
                }

                type  = data.ClrType;
                value = data.Original;
            }

            Type clrType;

            if (Mapping.CheckClrCompliance(type, out clrType, out exception) == ClrTypeMatch.ClrMatch)
            {
                if (clrType == typeof(System.Object))
                {
                    return(Text.Null);
                }

                return(Build(value, clrType));
            }
            else
            {
                return(null);
            }
        }
        internal BeginTableColumnChainer(Chainer prev, NonSelectColumnArgument column, Type type)
            : base(prev)
        {
            Type clrType;
            var  typeMatch = Mapping.CheckClrCompliance(type, out clrType, out chainException);

            if (typeMatch != Mapping.ClrTypeMatch.ClrMatch)
            {
                TryThrow();
            }

            var dataTypeDef = Mapping.ClrMapping[clrType].DefaultDataType;

            Initialize(column, dataTypeDef);
        }
示例#5
0
        private static Type StoreColumnInfo(List <ViewColumnInfo> columns, string columnName, Type columnType, bool?isNullable = null)
        {
            Type clrType;
            QueryTalkException exception;
            var clrMatch = Mapping.CheckClrCompliance(columnType, out clrType, out exception);

            if (clrMatch != Mapping.ClrTypeMatch.ClrMatch)
            {
                return(null);
            }

            ViewColumnInfo columnInfo = new ViewColumnInfo(columnName, columnType, clrType, isNullable);

            columns.Add(columnInfo);

            return(clrType);
        }
示例#6
0
        internal DeclareChainer(Chainer prev, string variableName, Type type)
            : base(prev)
        {
            _variableName = variableName;

            Type clrType;
            var  typeMatch = Mapping.CheckClrCompliance(type, out clrType, out chainException);

            if (typeMatch != Mapping.ClrTypeMatch.ClrMatch)
            {
                TryThrow();
            }

            var dataTypeDef = Mapping.ClrMapping[clrType].DefaultDataType;

            Initialize(dataTypeDef);
        }
示例#7
0
        private static List <JsonProperty> ReflectClass(Type type)
        {
            QueryTalkException exception;
            Type clrType;
            bool cached = false;

            List <JsonProperty> jsonCacheValue;

            cached = Cache.JsonCache.TryGetValue(type, out jsonCacheValue);
            if (!cached)
            {
                jsonCacheValue = new List <JsonProperty>();
                var properties = type.GetReadableProperties();
                var ix         = 0;
                var valid      = false;
                foreach (var property in properties)
                {
                    var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception);
                    if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                    {
                        continue;
                    }

                    if (!cached)
                    {
                        jsonCacheValue.Add(new JsonProperty(property.Name, clrType, PropertyAccessor.Create(type, property)));
                    }

                    ++ix;
                    valid = true;
                }

                if (!valid)
                {
                    throw new QueryTalkException("JsonConverter.ToJson<T>", QueryTalkExceptionType.InvalidDataClass,
                                                 String.Format("type = {0}", type), Text.Method.ToJson);
                }

                Cache.JsonCache[type] = jsonCacheValue;
            }

            return(jsonCacheValue);
        }
示例#8
0
        // design table using CLR type (converted into empty data view)
        internal static BeginTableChainer DesingByType <T>(Chainer prev, string tableName, bool skipTimestampColumn)
        {
            View view;

            // always convert QueryTalk compliant scalar type T into Row<T>
            Type clrType;
            QueryTalkException exception;

            if (Mapping.CheckClrCompliance(typeof(T), out clrType, out exception) == Mapping.ClrTypeMatch.ClrMatch)
            {
                view = Designer.ToView <Row <T> >();
            }
            else
            {
                view = Designer.ToView <T>();
            }

            return(new BeginTableChainer(prev, tableName, view, true, skipTimestampColumn));
        }
示例#9
0
        private static string ConvertDataTable(DataTable dataTable)
        {
            if (dataTable == null)
            {
                throw new QueryTalkException("JsonConverter.ConvertDataTable", QueryTalkExceptionType.ArgumentNull,
                                             "dataTable = null", Text.Method.ToJson);
            }

            if (dataTable.Columns.Count == 0)
            {
                throw new QueryTalkException("JsonConverter.ConvertDataTable", QueryTalkExceptionType.InvalidDataTable,
                                             "type = DataTable", Text.Method.ToJson);
            }

            var columns = new List <Tuple <string, Type> >();
            int i       = 0;
            var names   = new HashSet <string>();

            foreach (DataColumn column in dataTable.Columns)
            {
                Type clrType;
                QueryTalkException exception;
                if (Mapping.CheckClrCompliance(column.DataType, out clrType, out exception) != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                var name = Naming.GetClrColumnName(column.ColumnName, names, null, null);
                names.Add(name);

                columns.Add(Tuple.Create(name, clrType));
                ++i;
            }

            var  json  = new StringBuilder("[");
            bool first = true;

            foreach (var row in dataTable.AsEnumerable())
            {
                if (!first)
                {
                    json.AppendComma();
                }

                json.Append("{");
                for (int ix = 0; ix < i; ++ix)
                {
                    if (ix != 0)
                    {
                        json.AppendComma();
                    }

                    var value  = row[ix];
                    var column = columns[ix];

                    if (value == DBNull.Value)
                    {
                        value = null;
                    }

                    json.AppendFormat("\"{0}\":{1}", column.Item1, Mapping.ClrMapping[column.Item2].ToJson(value));
                }
                json.Append("}");

                first = false;
            }
            json.Append("]");

            return(json.ToString());
        }
示例#10
0
        internal static T SetClass <T>(T target, object source)

        {
            if (target == null)
            {
                throw new QueryTalkException("ClassConverter.ToClass", QueryTalkExceptionType.ArgumentNull,
                                             "target= null", Text.Method.Pack);
            }

            if (source == null)
            {
                throw new QueryTalkException("ClassConverter.ToClass", QueryTalkExceptionType.ArgumentNull,
                                             "source = null", Text.Method.Pack);
            }

            if (target != null && object.ReferenceEquals(target, source))
            {
                return(target);
            }

            Type targetType = target.GetType();
            Type sourceType = source.GetType();

            TryCheckClassType(targetType);
            TryCheckClassType(sourceType);

            var sourceProperties = sourceType.GetReadableProperties();
            var targetProperties = targetType.GetWritableProperties();

            if (targetProperties.Length == 0)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("type = {0}", targetType), Text.Method.Pack);
            }
            if (sourceProperties.Length == 0)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("type = {0}", sourceType), Text.Method.Pack);
            }

            bool match = false;
            Type clrType;
            QueryTalkException exception;

            foreach (var targetProperty in targetProperties)
            {
                var clrTypeMatch = Mapping.CheckClrCompliance(targetProperty.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                var sourceProperty = sourceProperties.Where(p => p.Name == targetProperty.Name).FirstOrDefault();
                if (sourceProperty != null)
                {
                    if (Common.GetClrType(sourceProperty.PropertyType) != Common.GetClrType(targetProperty.PropertyType))
                    {
                        throw new QueryTalkException("ClassConverter.ToClass", QueryTalkExceptionType.PackPropertyMismatch,
                                                     String.Format("target property name = {0}{1}   target property type = {2}{1}   source property type = {3}",
                                                                   targetProperty.Name, Environment.NewLine, targetProperty.PropertyType, sourceProperty.PropertyType),
                                                     Text.Method.Pack);
                    }

                    match = true;
                    targetProperty.SetValue(target, sourceProperty.GetValue(source, null), null);
                }
            }

            if (!match)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("target type = {0}{1}   source type = {2}",
                                                           targetType, Environment.NewLine, sourceType),
                                             Text.Method.Pack);
            }

            return(target);
        }
示例#11
0
        private static ColumnInfo[] ReflectReader(IDataRecord reader, out QueryTalkException exception)
        {
            exception = null;
            var       columns      = new List <Loader.ColumnInfo>();
            DataTable readerSchema = ((SqlDataReader)reader).GetSchemaTable();

            int           i           = 0;
            int           index       = 1;
            List <string> columnNames = new List <string>();

            foreach (var row in readerSchema.AsEnumerable())
            {
                Loader.ColumnInfo column = new ColumnInfo();
                column.ColumnName = Naming.GetClrName((string)row[_columnNameText]);

                if (String.IsNullOrEmpty(column.ColumnName))
                {
                    column.ColumnName = GetColumnName(readerSchema, ref index);
                }

                column.ReaderOrdinal = (int)row[_columnOrdinalText];
                column.ValueType     = (Type)row[_dataTypeText];

                Type clrType;
                if (Mapping.CheckClrCompliance(column.ValueType, out clrType, out exception) != Mapping.ClrTypeMatch.ClrMatch)
                {
                    exception = null;
                    continue;
                }

                if ((bool)row[_allowDBNullText] && !column.ValueType.IsClass)
                {
                    column.IsNullable   = true;
                    column.NullableType = Mapping.ClrMapping[column.ValueType].NullableType;
                }

                ClrMappingInfo mapping = Mapping.ClrMapping[column.ValueType];
                column.ReaderGetMethod = typeof(SqlDataReader).GetMethod(mapping.SqlDataReaderGetMethodName,
                                                                         new Type[] { typeof(int) });
                column.IsUnbox           = mapping.IsUnbox;
                column.CtorParameterType = mapping.CtorParameterType;

                // provide unique column name
                int j       = 1;
                var renamed = column.ColumnName;
                while (columnNames.Contains(renamed))
                {
                    renamed = String.Format("{0}{1}{2}",
                                            column.ColumnName,
                                            Text.Free.Renamed,
                                            j > 1 ? j.ToString() : String.Empty);
                    ++j;
                }
                if (j > 1)
                {
                    column.ColumnName = renamed;
                }

                columns.Add(column);
                columnNames.Add(column.ColumnName);
                ++i;
            }

            return(columns.ToArray());
        }
示例#12
0
        private static void _BuildClassOuterSelect(Type type, ref Type clrType, ref QueryTalkException exception, List <ViewColumnInfo> columns,
                                                   bool isEmpty, PropertyInfo[] properties, out List <IPropertyAccessor> getters, out int numberOfProperties,
                                                   StringBuilder sqlOuter, StringBuilder sqlEmpty)
        {
            numberOfProperties = properties.Length;
            if (numberOfProperties == 0)
            {
                throw new QueryTalkException("ViewConverter.ToView<T>", QueryTalkExceptionType.InvalidDataClass,
                                             String.Format("data class = {0}", type));
            }

            bool cached = Cache.PropertyAccessors.TryGetValue(type, out getters);

            if (!cached)
            {
                getters = new List <IPropertyAccessor>();
            }

            NodeMap rowMap  = null;
            bool    isDbRow = type.IsDbRow();

            if (isDbRow)
            {
                rowMap = DbMapping.GetNodeMap(type);
                if (rowMap.ID.Equals(DB3.Default))
                {
                    DbRow.ThrowInvalidDbRowException(type);
                }
            }

            // outer select:
            int i = 0;

            foreach (var property in properties)
            {
                string column;

                var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                ViewColumnInfo columnInfo;
                if (isDbRow)
                {
                    var rowColumn = rowMap.Columns.Where(a => a.ID.ColumnZ == i + 1).First();
                    column     = rowColumn.Name.Part1;
                    columnInfo = new ViewColumnInfo(column, rowColumn.DataType, rowColumn.IsNullable);
                    columns.Add(columnInfo);
                }
                else
                {
                    column     = property.Name;
                    columnInfo = new ViewColumnInfo(column, property.PropertyType, clrType);
                    columns.Add(columnInfo);
                }

                if (i != 0)
                {
                    sqlOuter.NewLineIndent(Text.Comma);
                    sqlEmpty.Append(Text.Comma);
                }

                var dataType = Mapping.ProvideDataType(columnInfo.DataType, clrType);
                AppendOuterColumn(sqlOuter, dataType, i + 1, column);

                if (isEmpty)
                {
                    AppendNullValueColumn(sqlEmpty, i + 1);
                }

                if (!cached)
                {
                    getters.Add(PropertyAccessor.Create(type, property));
                }

                ++i;
            }

            numberOfProperties = i;
            if (numberOfProperties == 0)
            {
                ThrowInvalidDataClassException(type);
            }

            if (!cached)
            {
                Cache.PropertyAccessors[type] = getters;
            }
        }
示例#13
0
        private static ColumnInfo[] ReflectRow(Type type, IDataRecord reader)
        {
            var properties = type.GetProperties();

            Type[] columnTypes = type.GetGenericArguments();
            Loader.ColumnInfo[] columns;
            string propertyName = Text.NotAvailable;
            int    columnCount  = columnTypes.Length;


            if (reader.FieldCount < columnTypes.Length)
            {
                throw new QueryTalkException("Loader.ReflectRow", QueryTalkExceptionType.NoMoreColumns,
                                             String.Format("QtRow = {0}{1}   Number of columns in data source = {2}",
                                                           type, Environment.NewLine, reader.FieldCount));
            }

            try
            {
                QueryTalkException exception;
                columns = new Loader.ColumnInfo[columnCount];
                for (int i = 0; i < columnCount; ++i)
                {
                    Type columnType = columnTypes[i];

                    Loader.ColumnInfo column   = new Loader.ColumnInfo();
                    PropertyInfo      property = properties[i];
                    propertyName = property.Name;
                    Type clrType;

                    if (Mapping.CheckClrCompliance(columnType, out clrType, out exception) != Mapping.ClrTypeMatch.ClrMatch)
                    {
                        exception.Arguments = String.Format("class = {0}{1}   property = {2}{3}   {4}",
                                                            type, Environment.NewLine, property.Name, Environment.NewLine, exception.Arguments);
                        throw exception;
                    }

                    ClrMappingInfo mapping;
                    if (columnType.IsNullable())
                    {
                        column.IsNullable = true;
                        column.ValueType  = Nullable.GetUnderlyingType(columnType);
                        mapping           = Mapping.ClrMapping[column.ValueType];
                    }
                    else
                    {
                        column.IsNullable = false;
                        column.ValueType  = columnType;
                        mapping           = Mapping.ClrMapping[columnType];
                    }

                    column.ReaderGetMethod = typeof(SqlDataReader).GetMethod(mapping.SqlDataReaderGetMethodName,
                                                                             new Type[] { typeof(int) });
                    column.ReaderOrdinal     = i;
                    column.Property          = property;
                    column.IsUnbox           = mapping.IsUnbox;
                    column.CtorParameterType = mapping.CtorParameterType;
                    column.ColumnName        = property.Name;
                    columns[i] = column;
                }

                return(columns);
            }
            catch (System.IndexOutOfRangeException)  // property name does not match any IDataReader field
            {
                throw new QueryTalkException("Reader.ReflectRow", QueryTalkExceptionType.MismatchedTargetColumn,
                                             String.Format("class = {0}{1}   property = {2}", type, Environment.NewLine, propertyName));
            }
        }
示例#14
0
        private static ColumnInfo[] ReflectClass(Type type, IDataRecord reader)
        {
            string propertyName = Text.NotAvailable;

            CheckParmeterlessConstructorAndThrow(type);

            PropertyInfo[] properties = type.GetWritableProperties();
            if (properties.Length == 0)
            {
                throw new QueryTalkException("Reader.ReflectClass<T>", QueryTalkExceptionType.InvalidDataClass,
                                             String.Format("data class = {0}", type));
            }

            var schema   = ((SqlDataReader)reader).GetSchemaTable();
            var clrNames = schema.AsEnumerable()
                           .Select(a => Naming.GetClrName(a.Field <string>(_columnNameText)))
                           .ToList();
            IEnumerable <string> duplicates;

            Common.FindDuplicates(clrNames, out duplicates);

            QueryTalkException exception;
            var columns = new List <Loader.ColumnInfo>();
            int i       = 0;

            foreach (PropertyInfo property in properties)
            {
                propertyName = property.Name;
                Loader.ColumnInfo column = new Loader.ColumnInfo();

                Type clrType;
                var  clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                ClrMappingInfo mapping;
                if (property.PropertyType.IsNullable())
                {
                    column.IsNullable = true;
                    column.ValueType  = Nullable.GetUnderlyingType(property.PropertyType);
                    mapping           = Mapping.ClrMapping[column.ValueType];
                }
                else
                {
                    column.IsNullable = false;
                    column.ValueType  = property.PropertyType;
                    mapping           = Mapping.ClrMapping[property.PropertyType];
                }

                var match = schema.AsEnumerable()
                            .Where(a => Naming.GetClrName(a.Field <string>(_columnNameText)).EqualsCS(property.Name))
                            .FirstOrDefault();

                // allow column mismatch - !
                if (match == null)
                {
                    continue;
                }

                if (duplicates.Contains(match.Field <string>(_columnNameText)))
                {
                    throw new QueryTalkException("Loader.ReflectReader", QueryTalkExceptionType.ColumnNameDuplicate,
                                                 String.Format("duplicate CLR name(s) = {0}", match.Field <string>(_columnNameText)));
                }

                int ordinal = match.Field <int>(_columnOrdinalText);
                column.ReaderGetMethod = typeof(SqlDataReader).GetMethod(mapping.SqlDataReaderGetMethodName,
                                                                         new Type[] { typeof(int) });
                column.ReaderOrdinal     = ordinal;
                column.Property          = property;
                column.IsUnbox           = mapping.IsUnbox;
                column.CtorParameterType = mapping.CtorParameterType;
                column.ColumnName        = property.Name;
                columns.Add(column);
                ++i;
            }

            return(columns.ToArray());
        }
示例#15
0
        internal static View ConvertCollection <T>(IEnumerable data)
        {
            var ctype = typeof(T);
            var type  = Common.TryGetSerializationItemType(ctype, data, Text.Method.ToView);

            if (type == null)
            {
                throw new QueryTalkException("Common.TryGetSerializationItemType",
                                             QueryTalkExceptionType.EmptyDynamicResult, String.Format("type = {0}", ctype), Text.Method.ToView);
            }

            Type clrType = null;
            QueryTalkException    exception;
            List <ViewColumnInfo> columns = new List <ViewColumnInfo>();

            bool isScalar = (Mapping.CheckClrCompliance(type, out clrType, out exception) == Mapping.ClrTypeMatch.ClrMatch);

            bool isDataValue = type == typeof(Value);

            if (isDataValue)
            {
                isScalar = true;
                clrType  = typeof(System.Object);
            }

            bool isEmpty    = _CheckIfEmpty(data, isScalar);
            var  properties = type.GetReadableProperties();
            List <IPropertyAccessor> getters = null;
            int numberOfProperties           = 0;
            var sqlOuter = Text.GenerateSql(500);

            var sqlEmpty = Text.GenerateSql(200)
                           .NewLineIndent(Text.Select).S();

            // outer select:
            if (isScalar)
            {
                _BuildScalarOuterSelect(type, clrType, columns, sqlOuter);
            }
            else
            {
                _BuildClassOuterSelect(type, ref clrType, ref exception, columns, isEmpty, properties, out getters,
                                       out numberOfProperties, sqlOuter, sqlEmpty);
            }

            // inner select:
            var sqlInner = Text.GenerateSql(500);
            int rowCount = 0;

            if (!isEmpty)
            {
                bool firstRow = true;
                foreach (var row in data)
                {
                    if (!isScalar && row == null)
                    {
                        continue;
                    }

                    _BuildSelect(sqlInner, firstRow);

                    if (!isScalar)
                    {
                        _BuildClassValues(columns, properties, getters, numberOfProperties, sqlInner, firstRow, row);
                    }
                    else
                    {
                        AppendColumn(sqlInner, Mapping.BuildUnchecked(row), Text.SingleColumnShortName);
                    }

                    firstRow = false;
                    ++rowCount;
                }
            }
            else
            {
                if (isScalar)
                {
                    AppendColumn(sqlEmpty, Text.Null, Text.SingleColumnShortName);
                }

                sqlInner.Append(sqlEmpty.ToString());
            }

            return(Finalizer(type, sqlOuter, sqlInner, columns.ToArray(), rowCount, isEmpty));
        }
示例#16
0
        internal static IEnumerable <T> PackRows <T>(IEnumerable source)
            where T : new()
        {
            if (source == null)
            {
                return(null);
            }

            Type targetType = typeof(T);
            Type sourceType = null;

            foreach (var row in source)
            {
                if (row == null)
                {
                    continue;
                }

                sourceType = row.GetType();
                break;
            }

            if (sourceType == null)
            {
                return(null);
            }

            TryCheckClassType(targetType);
            TryCheckClassType(sourceType);

            var sourceProperties = sourceType.GetReadableProperties();
            var targetProperties = targetType.GetWritableProperties();

            if (targetProperties.Length == 0)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("type = {0}", targetType), Text.Method.Pack);
            }
            if (sourceProperties.Length == 0)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("type = {0}", sourceType), Text.Method.Pack);
            }

            var sourceGetters = new List <IPropertyAccessor>();
            var targetGetters = new List <IPropertyAccessor>();

            bool match = false;
            Type clrType;
            QueryTalkException exception;
            var numberOfPropertiesUsed = 0;

            foreach (var targetProperty in targetProperties)
            {
                var clrTypeMatch = Mapping.CheckClrCompliance(targetProperty.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                var sourceProperty = sourceProperties.Where(p => p.Name == targetProperty.Name).FirstOrDefault();
                if (sourceProperty != null)
                {
                    if (Common.GetClrType(sourceProperty.PropertyType) != Common.GetClrType(targetProperty.PropertyType))
                    {
                        throw new QueryTalkException("ClassConverter.ToClass", QueryTalkExceptionType.PackPropertyMismatch,
                                                     String.Format("target property name = {0}{1}   target property type = {2}{1}   source property type = {3}",
                                                                   targetProperty.Name, Environment.NewLine, targetProperty.PropertyType, sourceProperty.PropertyType),
                                                     Text.Method.Pack);
                    }

                    match = true;

                    sourceGetters.Add(PropertyAccessor.Create(sourceType, sourceProperty));
                    targetGetters.Add(PropertyAccessor.Create(targetType, targetProperty));
                    ++numberOfPropertiesUsed;
                }
            }

            if (!match)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("target type = {0}{1}   source type = {2}",
                                                           targetType, Environment.NewLine, sourceType),
                                             Text.Method.Pack);
            }

            var rows = new HashSet <T>();

            foreach (var sourceRow in source)
            {
                if (sourceRow == null)
                {
                    continue;
                }

                var targetRow = new T();

                for (int i = 0; i < numberOfPropertiesUsed; i++)
                {
                    var value = sourceGetters[i].GetValue(sourceRow);
                    targetGetters[i].SetValue(targetRow, value);
                }

                rows.Add(targetRow);
            }

            return(rows);
        }
        private static string ConvertCollection(Type ctype, IEnumerable data)
        {
            var json = new StringBuilder("[", JsonConverter.StringBuilderCapacity);             // collection type
            var type = Common.TryGetSerializationItemType(ctype, data, Text.Method.ToJson);     // item type

            CollectionType      collectionType;
            ClrMappingInfo      clrInfo = null;
            Type                clrType;
            QueryTalkException  exception;
            List <JsonProperty> jsonProperties = null;

            // empty collection
            if (type == null)
            {
                collectionType = CollectionType.Object;
                data           = null;
            }
            else if (type == typeof(System.Object))
            {
                collectionType = CollectionType.Object;
            }
            else if (type == typeof(Value))
            {
                collectionType = CollectionType.Value;
            }
            // CLR compliant scalar type
            else if (Mapping.CheckClrCompliance(type, out clrType, out exception) == Mapping.ClrTypeMatch.ClrMatch)
            {
                collectionType = CollectionType.Clr;
                clrInfo        = Mapping.ClrMapping[clrType];
            }
            // class
            else
            {
                collectionType = CollectionType.Class;
                jsonProperties = ReflectClass(type);
            }

            var first = true;

            if (data != null)
            {
                foreach (var row in data)
                {
                    if (!first)
                    {
                        json.Append(",");
                    }

                    if (row.IsUndefined())
                    {
                        json.Append(Text.ClrNull);
                        first = false;
                        continue;
                    }

                    switch (collectionType)
                    {
                    case CollectionType.Object:
                        var rowType = row.GetType();
                        if (Mapping.CheckClrCompliance(rowType, out clrType, out exception) != Mapping.ClrTypeMatch.ClrMatch)
                        {
                            throw exception;
                        }
                        clrInfo = Mapping.ClrMapping[rowType];
                        json.Append(clrInfo.ToJson(row));
                        break;

                    case CollectionType.Value:
                        var o = ((Value)row).Original;
                        clrInfo = Mapping.ClrMapping[o.GetType()];
                        json.Append(clrInfo.ToJson(o));
                        break;

                    case CollectionType.Clr:
                        json.Append(clrInfo.ToJson(row));
                        break;

                    // class
                    default:
                        json.Append(ConvertClass(row, jsonProperties));
                        break;
                    }

                    first = false;
                }
            }

            json.Append("]");
            return(json.ToString());
        }