private void WriteEntity(Entity[] entities, Dictionary <string, Guid[]> resolvedEntities, Dictionary <string, AttributeMetadata> primaryKeyAttributeMetadataDictionary, ReportProgressMethod reportProgress)
        {
            List <Guid> entityIds = new List <Guid>();

            for (int i = 0; i < entities.Length; i++)
            {
                Entity entity = entities[i];
                entityIds.Clear();

                // Owner may not be written, so we need to temporarily store it
                EntityReference ownerid = null;
                if (entity.Contains("ownerid"))
                {
                    ownerid = entity["ownerid"] as EntityReference;
                    entity.Attributes.Remove("ownerid");
                }

                // Status may not be written, so we need to temporarily store it
                OptionSetValue statecode  = null;
                OptionSetValue statuscode = null;
                if (entity.Contains("statuscode"))
                {
                    statecode = entity["statecode"] as OptionSetValue;
                    entity.Attributes.Remove("statecode");

                    statuscode = entity["statuscode"] as OptionSetValue;
                    entity.Attributes.Remove("statuscode");
                }

                string entityKey = PrimaryKeyResolver.BuildExistingCheckKey(entity, primaryKeyAttributeMetadataDictionary);


                if (resolvedEntities[entityKey].Length == 0) // Create
                {
                    logger.SetBusinessKeyAndImportTypeForRecord(i, entityKey, ImportMode.Create);
                    CreateEntity(service, entity, entityKey, i, ownerid, statecode, statuscode, entityIds, resolvedEntities);
                }
                else // Update
                {
                    logger.SetBusinessKeyAndImportTypeForRecord(i, entityKey, ImportMode.Update);
                    UpdateEntity(service, entity, entityKey, i, ownerid, statecode, statuscode, entityIds, resolvedEntities);
                }

                if (StatusHelper.MustShowProgress(i, entities.Length) == true)
                {
                    reportProgress(new SimpleProgressReport("Wrote " + (i + 1) + " of " + entities.Length + " records"));
                }
            }
        }
        public void WriteData(IConnection connection, IDatabaseInterface databaseInterface, IDatastore dataObject, ReportProgressMethod reportProgress)
        {
            reportProgress(new SimpleProgressReport("Building logging database"));
            this.logger = new Logger(databaseInterface);
            this.logger.InitializeDatabase();

            reportProgress(new SimpleProgressReport("Connection to crm"));
            CrmConnection crmConnection = (CrmConnection)connection.GetConnection();

            service = new OrganizationService(crmConnection);

            reportProgress(new SimpleProgressReport("Loading Entitymetadata"));
            EntityMetadata entityMetaData = Crm2013Wrapper.Crm2013Wrapper.GetEntityMetadata(service, this.Configuration.EntityName);
            Dictionary <string, AttributeMetadata> primaryKeyAttributeMetadataDictionary = new Dictionary <string, AttributeMetadata>();

            foreach (string primaryKey in this.Configuration.PrimaryKeyAttributes)
            {
                AttributeMetadata attributeMetadata = entityMetaData.Attributes.Where(t => t.LogicalName == primaryKey).FirstOrDefault();
                primaryKeyAttributeMetadataDictionary.Add(primaryKey, attributeMetadata);
            }

            reportProgress(new SimpleProgressReport("Mapping attributes of records"));
            EntityMapper entityMapper = new EntityMapper(entityMetaData, dataObject.Metadata, this.Configuration.Mapping, this.Configuration.PicklistMapping);

            Entity[] entities = new Entity[dataObject.Count];
            for (int i = 0; i < dataObject.Count; i++)
            {
                object[] data = dataObject[i];

                Entity entity = new Entity(this.Configuration.EntityName);
                entityMapper.MapAttributes(entity, data);

                entities[i] = entity;
                logger.AddRecord(i);

                if (StatusHelper.MustShowProgress(i, dataObject.Count) == true)
                {
                    reportProgress(new SimpleProgressReport("Mapped " + (i + 1) + " of " + dataObject.Count + " records"));
                }
            }

            reportProgress(new SimpleProgressReport("Resolving relationship entities"));

            foreach (var relationMapping in Configuration.RelationMapping)
            {
                reportProgress(new SimpleProgressReport("Resolving relationship - load metadata for entity " + relationMapping.EntityName));
                EntityMetadata relationEntityMetadata = Crm2013Wrapper.Crm2013Wrapper.GetEntityMetadata(service, relationMapping.EntityName);

                reportProgress(new SimpleProgressReport("Resolving relationship - load related records"));
                JoinResolver relationResolver = new JoinResolver(service, relationEntityMetadata, relationMapping.Mapping);
                Dictionary <string, Guid[]> relatedEntities = relationResolver.BuildMassResolverIndex();

                reportProgress(new SimpleProgressReport("Resolving relationship - set relations"));

                RelationSetter relationSetter = new RelationSetter(relationEntityMetadata, relationMapping.Mapping);
                relationSetter.SetRelation(relationMapping.LogicalName, entities, dataObject, relatedEntities);
            }

            reportProgress(new SimpleProgressReport("Resolving primarykeys of records"));
            PrimaryKeyResolver          primaryKeyResolver = new PrimaryKeyResolver(service, entityMetaData, primaryKeyAttributeMetadataDictionary);
            Dictionary <string, Guid[]> resolvedEntities   = primaryKeyResolver.OneByOneResolver(entities);

            reportProgress(new SimpleProgressReport("Writing records to crm"));
            WriteEntity(entities, resolvedEntities, primaryKeyAttributeMetadataDictionary, reportProgress);
        }