private static void AddData(Type type, IEnumerable <IData> dataset, IWritableDataProvider dataProvider)
        {
            // TODO: check if adding in groups of ~1000 records may improve the performance
            MethodInfo genericMethod = StaticReflection.GetGenericMethodInfo((a) => AddData <IData>(null, null));

            genericMethod.MakeGenericMethod(new[] { type }).Invoke(null, new object[] { dataset, dataProvider });
        }
 private static void AddData <T>(IEnumerable <IData> dataset, IWritableDataProvider dataProvider) where T : class, IData
 {
     dataProvider.AddNew(dataset.Cast <T>());
 }
        private void CopyData(Type interfaceType)
        {
            IWritableDataProvider targetDataProvider = DataProviderPluginFacade.GetDataProvider(TargetProviderName) as IWritableDataProvider;

            Verify.IsNotNull(targetDataProvider, "Failed to get target data provider, probably it's not writeable.");

            foreach (DataScopeIdentifier dataScopeIdentifier in interfaceType.GetSupportedDataScopes())
            {
                Log.LogVerbose(LogTitle, "Copying scope '{0}' data for type '{1}'".FormatWith(dataScopeIdentifier.Name, interfaceType.FullName));

                foreach (CultureInfo cultureInfo in GetSupportedCultures(interfaceType))
                {
                    using (new DataScope(dataScopeIdentifier, cultureInfo))
                    {
                        List <IData> dataset;
                        try
                        {
                            dataset = DataFacade.GetData(interfaceType, SourceProviderName).ToDataList();

                            if (_specialHandleInterfaces.ContainsKey(interfaceType))
                            {
                                _specialHandleInterfaces[interfaceType](dataset, this.SourceProviderName,
                                                                        this.TargetProviderName);
                            }
                        }
                        catch (Exception)
                        {
                            Log.LogCritical(LogTitle, "Failed to read data from type '{0}'. See the log for the details."
                                            .FormatWith(interfaceType.FullName));
                            throw;
                        }


                        List <IData>     filteredDataset = null;
                        HashSet <string> dataIDs         = null;

                        if (IgnorePrimaryKeyViolation)
                        {
                            filteredDataset = new List <IData>();
                            dataIDs         = new HashSet <string>();
                        }

                        foreach (var data in dataset)
                        {
                            if (IgnorePrimaryKeyViolation)
                            {
                                string dataId = data.DataSourceId.ToString();
                                if (dataIDs.Contains(dataId))
                                {
                                    LoggingService.LogWarning(LogTitle, "Cannot insert a data row, since it's data ID is already used. DataID: '{0}'".FormatWith(dataId));
                                    continue;
                                }
                                dataIDs.Add(dataId);

                                filteredDataset.Add(data);
                            }
                            FixData(data);
                        }

                        if (IgnorePrimaryKeyViolation)
                        {
                            dataIDs = null;
                            dataset = filteredDataset;
                        }

                        try
                        {
                            AddData(interfaceType, dataset, targetDataProvider);
                        }
                        catch (Exception e)
                        {
                            Log.LogError(LogTitle, $"Adding failed while adding {interfaceType.Namespace}.{interfaceType.Name} because {e.Message}");
                            Log.LogError(LogTitle, e.InnerException);
                            throw;
                        }
                    }
                }
            }
        }