public virtual void Insert(IStructureSchema structureSchema, IStructure[] structures)
        {
            var groupedIndexInsertActions = new IndexInsertAction[0];

            Task task = null;

            try
            {
                task = Task.Factory.StartNew(
                    () => groupedIndexInsertActions = CreateGroupedIndexInsertActions(structureSchema, structures));

                InsertStructures(structureSchema, structures);
                InsertUniques(structureSchema, structures);

                Task.WaitAll(task);
            }
            finally
            {
                if (task != null && task.Status == TaskStatus.RanToCompletion)
                {
                    task.Dispose();
                }
            }

            if (!groupedIndexInsertActions.Any())
            {
                return;
            }

            InsertIndexes(groupedIndexInsertActions);
        }
        public virtual void Insert(IStructureSchema structureSchema, IStructure[] structures)
        {
            var groupedIndexInsertActions = new IndexInsertAction[0];

            Task task = null;
            try
            {
                task = Task.Factory.StartNew(
                    () => groupedIndexInsertActions = CreateGroupedIndexInsertActions(structureSchema, structures));

                InsertStructures(structureSchema, structures);
                InsertUniques(structureSchema, structures);

                Task.WaitAll(task);
            }
            finally
            {
                if (task != null && task.Status == TaskStatus.RanToCompletion)
                    task.Dispose();
            }

            if (!groupedIndexInsertActions.Any())
                return;

            InsertIndexes(groupedIndexInsertActions);
        }
        protected virtual IndexInsertAction CreateIndexInsertActionGroup(IStructureSchema structureSchema, IndexesTableNames indexesTableNames, DataTypeCode dataTypeCode, IStructureIndex[] indexes)
        {
            var container = new IndexInsertAction {
                Data = indexes
            };

            switch (dataTypeCode)
            {
            case DataTypeCode.IntegerNumber:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.IntegersTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.IntegersTableName);
                }
                break;

            case DataTypeCode.FractalNumber:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.FractalsTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.FractalsTableName);
                }
                break;

            case DataTypeCode.Bool:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.BooleansTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.BooleansTableName);
                }
                break;

            case DataTypeCode.DateTime:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.DatesTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.DatesTableName);
                }
                break;

            case DataTypeCode.Guid:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.GuidsTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.GuidsTableName);
                }
                break;

            case DataTypeCode.String:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new StringIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.StringsTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.StringsTableName);
                }
                break;

            case DataTypeCode.Enum:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new StringIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.StringsTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.StringsTableName);
                }
                break;

            case DataTypeCode.Text:
                if (container.Data.Length > 1)
                {
                    container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new TextIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.TextsTableName), data));
                }
                if (container.Data.Length == 1)
                {
                    container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.TextsTableName);
                }
                break;

            default:
                container.Action = null;
                break;
            }

            return(container);
        }
 protected virtual void InsertIndexes(IndexInsertAction[] groupedIndexInsertActions)
 {
     foreach (var groupedIndexInsertAction in groupedIndexInsertActions.Where(i => i.Action != null))
         groupedIndexInsertAction.Action.Invoke(groupedIndexInsertAction.Data, MainDbClient);
 }
        protected virtual IndexInsertAction CreateIndexInsertActionGroup(IStructureSchema structureSchema, IndexesTableNames indexesTableNames, DataTypeCode dataTypeCode, IStructureIndex[] indexes)
        {
            var container = new IndexInsertAction { Data = indexes };

            switch (dataTypeCode)
            {
                case DataTypeCode.IntegerNumber:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.IntegersTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.IntegersTableName);
                    break;
                case DataTypeCode.FractalNumber:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.FractalsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.FractalsTableName);
                    break;
                case DataTypeCode.Bool:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.BooleansTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.BooleansTableName);
                    break;
                case DataTypeCode.DateTime:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.DatesTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.DatesTableName);
                    break;
                case DataTypeCode.Guid:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new ValueTypeIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.GuidsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfValueTypeIndex(data[0], indexesTableNames.GuidsTableName);
                    break;
                case DataTypeCode.String:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new StringIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.StringsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.StringsTableName);
                    break;
                case DataTypeCode.Enum:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new StringIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.StringsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.StringsTableName);
                    break;
                case DataTypeCode.Text:
                    if (container.Data.Length > 1)
                        container.Action = (data, dbClient) => dbClient.BulkInsertIndexes(new TextIndexesReader(new IndexStorageSchema(structureSchema, indexesTableNames.TextsTableName), data));
                    if (container.Data.Length == 1)
                        container.Action = (data, dbClient) => dbClient.SingleInsertOfStringTypeIndex(data[0], indexesTableNames.TextsTableName);
                    break;
                default:
                    container.Action = null;
                    break;
            }

            return container;
        }