/// <summary> /// Deletes the profile. /// </summary> /// <param name="profile">The profile.</param> public void DeleteProfile(TransportationProfile profile) { //Refresh Profiles in case some other instance is updating the profiles ReadProfiles(); for (int i = 0; i < Profiles.Count; i++) { if (Profiles[i].ProfileName == profile.ProfileName) { Profiles.RemoveAt(i); } } //Delete Profile folder try { if (Directory.Exists(Folder + "\\" + profile.ProfileName)) { Directory.Delete(Folder + "\\" + profile.ProfileName, true); } } catch (Exception) { throw; } //Save Profiles WriteProfiles(); }
/// <summary> /// Runs the profile. /// </summary> /// <param name="profile">The profile.</param> /// <returns></returns> public string RunProfile(TransportationProfile profile) { LogManager.WriteLog("Running Transportation Profile: " + profile.ProfileName); //Check if there are selected entities to transport if (profile.SelectedEntities == null || profile.SelectedEntities.Count == 0) { LogManager.WriteLog("No entities selected for transport. Select the entities and then run the profile"); return(""); } DateTime now = DateTime.Now; ReportFileName = Folder + "\\" + profile.ProfileName + "\\ExecutionReports\\TransportReport" + now.Year + "-" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second + ".xml"; importFailuresReportFileName = Folder + "\\" + profile.ProfileName + "\\ExecutionReports\\ImportFailuresReport" + now.Year + "-" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second + ".xml"; //Initialize Execution Reports folder string executionReportsFolder = Folder + "\\" + profile.ProfileName + "\\ExecutionReports"; if (!Directory.Exists(executionReportsFolder)) { Directory.CreateDirectory(executionReportsFolder); } //Create Transport Report TransportReport tr = new TransportReport(profile.ProfileName); WriteTransportReport(tr, ReportFileName); //Check for the Operation to execute if (profile.Operation == 0) { //Export data Export(profile, ReportFileName); } else if (profile.Operation == 1) { //Import Data Import(profile, ReportFileName); } else if (profile.Operation == 2) { //Transport data => Export + Import Export(profile, ReportFileName); Import(profile, ReportFileName); } TransportReport report = ReadTransportReport(ReportFileName); report.TransportFinishedAt = DateTime.Now.ToString(); report.TransportCompleted = true; TimeSpan TransportTimeSpan = DateTime.Now - Convert.ToDateTime(report.TransportStartedAt); report.TransportedIn = TransportTimeSpan.ToString().Substring(0, 10); WriteTransportReport(report, ReportFileName); return(ReportFileName); }
/// <summary> /// Creates the profile. /// </summary> /// <param name="profile">The profile.</param> public void CreateProfile(TransportationProfile profile) { if (!Directory.Exists(Folder + "\\" + profile.ProfileName)) Directory.CreateDirectory(Folder + "\\" + profile.ProfileName); //Refresh Transportation Profiles in case some other instance is updating the profiles ReadProfiles(); //Creating new Transportation Profile Profiles.Add(profile); WriteProfiles(); }
/// <summary> /// Creates the profile. /// </summary> /// <param name="profile">The profile.</param> public void CreateProfile(TransportationProfile profile) { if (!Directory.Exists(Folder + "\\" + profile.ProfileName)) { Directory.CreateDirectory(Folder + "\\" + profile.ProfileName); } //Refresh Transportation Profiles in case some other instance is updating the profiles ReadProfiles(); //Creating new Transportation Profile Profiles.Add(profile); WriteProfiles(); }
/// <summary> /// Updates the profile. /// </summary> /// <param name="profile">The profile.</param> public void UpdateProfile(TransportationProfile profile) { if (!Directory.Exists(Folder + "\\" + profile.ProfileName)) { Directory.CreateDirectory(Folder + "\\" + profile.ProfileName); } //Refresh Transportation Profiles in case some other instance is updating the profiles ReadProfiles(); for (int i = 0; i < Profiles.Count; i++) { if (Profiles[i].ProfileName == profile.ProfileName) { Profiles[i] = profile; break; } } WriteProfiles(); }
/// <summary> /// Maps the records. /// </summary> /// <param name="profile">The profile.</param> /// <param name="entity">The entity.</param> /// <returns>The Mapped Record</returns> public Entity MapRecords(TransportationProfile profile, Entity entity) { if (profile.RecordMappings == null || profile.RecordMappings.Count == 0) { return(entity); } List <KeyValuePair <string, object> > kvList = new List <KeyValuePair <string, object> >(); foreach (KeyValuePair <string, object> p in entity.Attributes) { Type t = p.Value.GetType(); if (t.Name == "EntityReference") { kvList.Add(p); } } foreach (KeyValuePair <string, object> kv in kvList) { EntityReference er = (EntityReference)kv.Value; RecordMapping rmList = profile.RecordMappings.Find(rm => rm.EntityName == er.LogicalName && rm.SourceRecordId == er.Id); if (rmList == null) { continue; } entity[kv.Key] = new EntityReference { Id = rmList.TargetRecordId, LogicalName = rmList.EntityName }; } return(entity); }
/// <summary> /// Exports the entity. /// </summary> /// <param name="profile">The profile.</param> /// <param name="fetchXml">The fetch XML.</param> /// <returns></returns> public int ExportEntity(TransportationProfile profile, string fetchXml) { //Set the number of records per page to retrieve. //This value should not be bigger than 5000 as this is the limit of records provided by the CRM int fetchCount = 5000; // Initialize the file number. int fileNumber = 1; // Initialize the number of records. int recordCount = 0; // Specify the current paging cookie. For retrieving the first page, pagingCookie should be null. string pagingCookie = null; string entityName = ""; while (true) { // Build fetchXml string with the placeholders. string xml = CreateXml(fetchXml, pagingCookie, fileNumber, fetchCount); // Execute the fetch query and get the xml result. RetrieveMultipleRequest fetchRequest = new RetrieveMultipleRequest { Query = new FetchExpression(xml) }; EntityCollection returnCollection = ((RetrieveMultipleResponse)_serviceProxy.Execute(fetchRequest)).EntityCollection; recordCount += returnCollection.Entities.Count; if (recordCount > 0) { string entityFolderName = Folder + "\\" + profile.ProfileName + "\\Data\\" + returnCollection.EntityName; entityName = returnCollection.EntityName; if (!Directory.Exists(entityFolderName)) Directory.CreateDirectory(entityFolderName); List<Type> knownTypes = new List<Type>(); knownTypes.Add(typeof(Entity)); int fileCpt = 1000000 + fileNumber; string filename = entityFolderName + "\\" + fileCpt + ".xml"; FileStream writer = new FileStream(filename, FileMode.Create); DataContractSerializer ser = new DataContractSerializer(typeof(EntityCollection), knownTypes); ser.WriteObject(writer, returnCollection); writer.Close(); } // Check for more records, if it returns 1. if (returnCollection.MoreRecords) { // Increment the page number to retrieve the next page. fileNumber++; pagingCookie = returnCollection.PagingCookie; } else { // If no more records in the result nodes, exit the loop. break; } } if (recordCount > 0) { //Save Exported Entites number foreach (SelectedEntity ee in profile.SelectedEntities) { if (entityName == ee.EntityName) { ee.ExportedRecords = recordCount; } } profile.TotalExportedRecords += recordCount; UpdateProfile(profile); } LogManager.WriteLog("Exported " + recordCount + " " + entityName + " records."); return recordCount; }
/// <summary> /// Exports the entity. /// </summary> /// <param name="profile">The profile.</param> /// <param name="fetchXml">The fetch XML.</param> /// <returns></returns> public int ExportEntity(TransportationProfile profile, string fetchXml) { //Set the number of records per page to retrieve. //This value should not be bigger than 5000 as this is the limit of records provided by the CRM int fetchCount = 5000; // Initialize the file number. int fileNumber = 1; // Initialize the number of records. int recordCount = 0; // Specify the current paging cookie. For retrieving the first page, pagingCookie should be null. string pagingCookie = null; string entityName = ""; while (true) { // Build fetchXml string with the placeholders. string xml = CreateXml(fetchXml, pagingCookie, fileNumber, fetchCount); // Execute the fetch query and get the xml result. RetrieveMultipleRequest fetchRequest = new RetrieveMultipleRequest { Query = new FetchExpression(xml) }; EntityCollection returnCollection = ((RetrieveMultipleResponse)_serviceProxy.Execute(fetchRequest)).EntityCollection; recordCount += returnCollection.Entities.Count; if (recordCount > 0) { string entityFolderName = Folder + "\\" + profile.ProfileName + "\\Data\\" + returnCollection.EntityName; entityName = returnCollection.EntityName; if (!Directory.Exists(entityFolderName)) { Directory.CreateDirectory(entityFolderName); } List <Type> knownTypes = new List <Type>(); knownTypes.Add(typeof(Entity)); int fileCpt = 1000000 + fileNumber; string filename = entityFolderName + "\\" + fileCpt + ".xml"; FileStream writer = new FileStream(filename, FileMode.Create); DataContractSerializer ser = new DataContractSerializer(typeof(EntityCollection), knownTypes); ser.WriteObject(writer, returnCollection); writer.Close(); } // Check for more records, if it returns 1. if (returnCollection.MoreRecords) { // Increment the page number to retrieve the next page. fileNumber++; pagingCookie = returnCollection.PagingCookie; } else { // If no more records in the result nodes, exit the loop. break; } } if (recordCount > 0) { //Save Exported Entites number foreach (SelectedEntity ee in profile.SelectedEntities) { if (entityName == ee.EntityName) { ee.ExportedRecords = recordCount; } } profile.TotalExportedRecords += recordCount; UpdateProfile(profile); } LogManager.WriteLog("Exported " + recordCount + " " + entityName + " records."); return(recordCount); }
private void newToolStripMenuItem_Click(object sender, EventArgs e) { currentProfile = null; textBoxTransportationProfileName.Text = ""; comboBoxImportMode.SelectedIndex = 0; comboBoxConnectionSource.SelectedItem = null; comboBoxConnectionTarget.SelectedItem = null; comboBoxTransportationProfiles.SelectedItem = null; comboBoxOperation.SelectedIndex = 2; comboBoxImportMode.SelectedIndex = 1; }
/// <summary> /// Maps the records. /// </summary> /// <param name="profile">The profile.</param> /// <param name="entity">The entity.</param> /// <returns>The Mapped Record</returns> public Entity MapRecords(TransportationProfile profile, Entity entity) { if (profile.RecordMappings == null || profile.RecordMappings.Count == 0) return entity; List<KeyValuePair<string, object>> kvList = new List<KeyValuePair<string, object>>(); foreach (KeyValuePair<string, object> p in entity.Attributes) { Type t = p.Value.GetType(); if (t.Name == "EntityReference") kvList.Add(p); } foreach (KeyValuePair<string, object> kv in kvList) { EntityReference er = (EntityReference)kv.Value; RecordMapping rmList = profile.RecordMappings.Find(rm => rm.EntityName == er.LogicalName && rm.SourceRecordId == er.Id); if (rmList == null) continue; entity[kv.Key] = new EntityReference { Id = rmList.TargetRecordId, LogicalName = rmList.EntityName }; } return entity; }
/// <summary> /// Deletes the profile. /// </summary> /// <param name="profile">The profile.</param> public void DeleteProfile(TransportationProfile profile) { //Refresh Profiles in case some other instance is updating the profiles ReadProfiles(); for (int i = 0; i < Profiles.Count; i++) { if (Profiles[i].ProfileName == profile.ProfileName) { Profiles.RemoveAt(i); } } //Delete Profile folder try { if (Directory.Exists(Folder + "\\" + profile.ProfileName)) Directory.Delete(Folder + "\\" + profile.ProfileName, true); } catch (Exception) { throw; } //Save Profiles WriteProfiles(); }
private void deleteProfileToolStripMenuItem_Click(object sender, EventArgs e) { string currentTransportationProfileName = currentProfile.ProfileName; DialogResult dResTest; dResTest = MessageBox.Show("Are you sure you want to delete this Transportation Profile ?", "Confirm Profile Deletion", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dResTest == DialogResult.No) { return; } else { comboBoxTransportationProfiles.Items.Remove(currentProfile.ProfileName); comboBoxTransportationProfiles.SelectedItem = null; man.DeleteProfile(currentProfile); currentProfile = null; textBoxTransportationProfileName.Text = ""; labelStructureLastLoadedDate.Text = "never"; textBoxTransportationProfileName.Enabled = true; comboBoxConnectionSource.SelectedItem = null; comboBoxConnectionTarget.SelectedItem = null; comboBoxOperation.SelectedIndex = 2; comboBoxImportMode.SelectedIndex = 1; toolStripStatusLabel.Text = "Transportation Profile " + currentTransportationProfileName + " deleted"; } }
/// <summary> /// Imports the specified profile. /// </summary> /// <param name="profile">The profile.</param> /// <param name="transportReportFileName">Name of the transport report file.</param> private void Import(TransportationProfile profile, string transportReportFileName) { int totalTreatedRecords = 0; int totalImportFailures = 0; int totalImportSuccess = 0; int ReconnectionRetryCount = 5; try { TransportReport report = new TransportReport(transportReportFileName); //Get Transport Report if (File.Exists(transportReportFileName)) { report = ReadTransportReport(transportReportFileName); } MSCRMConnection connection = profile.getTargetConneciton();; _serviceProxy = cm.connect(connection); IOrganizationService service = (IOrganizationService)_serviceProxy; LogManager.WriteLog("Start importing data in " + connection.ConnectionName); //Mesure import time DateTime importStartDT = DateTime.Now; //Order import according to profile's import order IOrderedEnumerable <SelectedEntity> orderedSelectedEntities = profile.SelectedEntities.OrderBy(e => e.TransportOrder); foreach (SelectedEntity ee in orderedSelectedEntities) { //Check if there are any records to import if (ee.ExportedRecords == 0) { continue; } //Mesure import time DateTime entityImportStartDT = DateTime.Now; string entityFolderPath = Folder + "\\" + profile.ProfileName + "\\Data\\" + ee.EntityName; string[] filePaths = Directory.GetFiles(entityFolderPath, "*.xml"); LogManager.WriteLog("Importing " + ee.EntityName + " records."); int treatedRecordsForEntity = 0; int importedRecordsForEntity = 0; int importFailuresForEntity = 0; foreach (string filePath in filePaths) { List <Type> knownTypes = new List <Type>(); knownTypes.Add(typeof(Entity)); XmlDictionaryReaderQuotas XRQ = new XmlDictionaryReaderQuotas(); XRQ.MaxStringContentLength = int.MaxValue; using (FileStream fs = new FileStream(filePath, FileMode.Open)) using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, XRQ)) { DataContractSerializer ser = new DataContractSerializer(typeof(EntityCollection), knownTypes); EntityCollection fromDisk = (EntityCollection)ser.ReadObject(reader, true); foreach (Entity e in fromDisk.Entities) { //Records mapping for the Lookup attributes Entity entity = MapRecords(profile, e); string executingOperation = ""; try { if (profile.ImportMode == 0) { executingOperation = "Create"; service.Create(entity); } else if (profile.ImportMode == 1) { try { executingOperation = "Update"; service.Update(entity); } catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> ) { executingOperation = "Create"; service.Create(entity); } } else if (profile.ImportMode == 2) { executingOperation = "Update"; service.Update(entity); } importedRecordsForEntity++; totalImportSuccess++; } catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { totalImportFailures++; importFailuresForEntity++; ImportFailure failure = new ImportFailure { CreatedOn = DateTime.Now.ToString(), EntityName = ee.EntityName, Operation = executingOperation, Reason = ex.Detail.Message, Url = profile.getSourceConneciton().ServerAddress + "main.aspx?pagetype=entityrecord&etn=" + ee.EntityName + "&id=" + entity.Id.ToString() }; report.TotalImportFailures += 1; //Insert the Failure line in the Failures Report WriteNewImportFailureLine(failure, importFailuresReportFileName); } catch (Exception ex) { //Check if the authentification session is expired if (ex.InnerException != null && ex.InnerException.Message.StartsWith("ID3242")) { LogManager.WriteLog("Error:The CRM authentication session expired. Reconnection attempt n° " + ReconnectionRetryCount); ReconnectionRetryCount--; //On 5 failed reconnections exit if (ReconnectionRetryCount == 0) { throw; } _serviceProxy = cm.connect(connection); service = (IOrganizationService)_serviceProxy; LogManager.WriteLog("Error:The CRM authentication session expired."); totalImportFailures++; importFailuresForEntity++; ImportFailure failure = new ImportFailure { CreatedOn = DateTime.Now.ToString(), EntityName = ee.EntityName, Operation = executingOperation, Reason = ex.InnerException.Message, Url = profile.getSourceConneciton().ServerAddress + "main.aspx?pagetype=entityrecord&etn=" + ee.EntityName + "&id=" + entity.Id.ToString() }; report.TotalImportFailures += 1; //Insert the Failure line in the Failures Report WriteNewImportFailureLine(failure, importFailuresReportFileName); } else { throw; } } totalTreatedRecords++; treatedRecordsForEntity++; updateTransportReport(report, ee, importedRecordsForEntity, importFailuresForEntity, entityImportStartDT); } } } LogManager.WriteLog("Treated " + treatedRecordsForEntity + " " + ee.EntityName + " records with " + importedRecordsForEntity + " successfully imported records and " + importFailuresForEntity + " failures."); } TimeSpan importTimeSpan = DateTime.Now - importStartDT; LogManager.WriteLog("Import finished for " + connection.ConnectionName + ". Treated " + totalTreatedRecords + " records in " + importTimeSpan.ToString().Substring(0, 10) + ". Successfuly imported " + totalImportSuccess + " records and " + totalImportFailures + " failures."); //WriteTransportReport(report, transportReportFileName); } catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { LogManager.WriteLog("Error:" + ex.Detail.Message + "\n" + ex.Detail.TraceText); } catch (Exception ex) { if (ex.InnerException != null) { LogManager.WriteLog("Error:" + ex.Message + "\n" + ex.InnerException.Message); } else { LogManager.WriteLog("Error:" + ex.Message); } } }
/// <summary> /// Runs the profile. /// </summary> /// <param name="profile">The profile.</param> /// <returns></returns> public string RunProfile(TransportationProfile profile) { LogManager.WriteLog("Running Transportation Profile: " + profile.ProfileName); //Check if there are selected entities to transport if (profile.SelectedEntities == null || profile.SelectedEntities.Count == 0) { LogManager.WriteLog("No entities selected for transport. Select the entities and then run the profile"); return ""; } DateTime now = DateTime.Now; ReportFileName = Folder + "\\" + profile.ProfileName + "\\ExecutionReports\\TransportReport" + now.Year + "-" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second + ".xml"; importFailuresReportFileName = Folder + "\\" + profile.ProfileName + "\\ExecutionReports\\ImportFailuresReport" + now.Year + "-" + now.Month + "-" + now.Day + "-" + now.Hour + "-" + now.Minute + "-" + now.Second + ".xml"; //Initialize Execution Reports folder string executionReportsFolder = Folder + "\\" + profile.ProfileName + "\\ExecutionReports"; if (!Directory.Exists(executionReportsFolder)) { Directory.CreateDirectory(executionReportsFolder); } //Create Transport Report TransportReport tr = new TransportReport(profile.ProfileName); WriteTransportReport(tr, ReportFileName); //Check for the Operation to execute if (profile.Operation == 0) { //Export data Export(profile, ReportFileName); } else if (profile.Operation == 1) { //Import Data Import(profile, ReportFileName); } else if (profile.Operation == 2) { //Transport data => Export + Import Export(profile, ReportFileName); Import(profile, ReportFileName); } TransportReport report = ReadTransportReport(ReportFileName); report.TransportFinishedAt = DateTime.Now.ToString(); report.TransportCompleted = true; TimeSpan TransportTimeSpan = DateTime.Now - Convert.ToDateTime(report.TransportStartedAt); report.TransportedIn = TransportTimeSpan.ToString().Substring(0, 10); WriteTransportReport(report, ReportFileName); return ReportFileName; }
/// <summary> /// Imports the specified profile. /// </summary> /// <param name="profile">The profile.</param> /// <param name="transportReportFileName">Name of the transport report file.</param> private void Import(TransportationProfile profile, string transportReportFileName) { int totalTreatedRecords = 0; int totalImportFailures = 0; int totalImportSuccess = 0; int ReconnectionRetryCount = 5; try { TransportReport report = new TransportReport(transportReportFileName); //Get Transport Report if (File.Exists(transportReportFileName)) { report = ReadTransportReport(transportReportFileName); } MSCRMConnection connection = profile.getTargetConneciton(); ; _serviceProxy = cm.connect(connection); IOrganizationService service = (IOrganizationService)_serviceProxy; LogManager.WriteLog("Start importing data in " + connection.ConnectionName); //Mesure import time DateTime importStartDT = DateTime.Now; //Order import according to profile's import order IOrderedEnumerable<SelectedEntity> orderedSelectedEntities = profile.SelectedEntities.OrderBy(e => e.TransportOrder); foreach (SelectedEntity ee in orderedSelectedEntities) { //Check if there are any records to import if (ee.ExportedRecords == 0) { continue; } //Mesure import time DateTime entityImportStartDT = DateTime.Now; string entityFolderPath = Folder + "\\" + profile.ProfileName + "\\Data\\" + ee.EntityName; string[] filePaths = Directory.GetFiles(entityFolderPath, "*.xml"); LogManager.WriteLog("Importing " + ee.EntityName + " records."); int treatedRecordsForEntity = 0; int importedRecordsForEntity = 0; int importFailuresForEntity = 0; foreach (string filePath in filePaths) { List<Type> knownTypes = new List<Type>(); knownTypes.Add(typeof(Entity)); XmlDictionaryReaderQuotas XRQ = new XmlDictionaryReaderQuotas(); XRQ.MaxStringContentLength = int.MaxValue; using (FileStream fs = new FileStream(filePath, FileMode.Open)) using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, XRQ)) { DataContractSerializer ser = new DataContractSerializer(typeof(EntityCollection), knownTypes); EntityCollection fromDisk = (EntityCollection)ser.ReadObject(reader, true); foreach (Entity e in fromDisk.Entities) { //Records mapping for the Lookup attributes Entity entity = MapRecords(profile, e); string executingOperation = ""; try { if (profile.ImportMode == 0) { executingOperation = "Create"; service.Create(entity); } else if (profile.ImportMode == 1) { try { executingOperation = "Update"; service.Update(entity); } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>) { executingOperation = "Create"; service.Create(entity); } } else if (profile.ImportMode == 2) { executingOperation = "Update"; service.Update(entity); } importedRecordsForEntity++; totalImportSuccess++; } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { totalImportFailures++; importFailuresForEntity++; ImportFailure failure = new ImportFailure { CreatedOn = DateTime.Now.ToString(), EntityName = ee.EntityName, Operation = executingOperation, Reason = ex.Detail.Message, Url = profile.getSourceConneciton().ServerAddress + "main.aspx?pagetype=entityrecord&etn=" + ee.EntityName + "&id=" + entity.Id.ToString() }; report.TotalImportFailures += 1; //Insert the Failure line in the Failures Report WriteNewImportFailureLine(failure, importFailuresReportFileName); } catch (Exception ex) { //Check if the authentification session is expired if (ex.InnerException != null && ex.InnerException.Message.StartsWith("ID3242")) { LogManager.WriteLog("Error:The CRM authentication session expired. Reconnection attempt n° " + ReconnectionRetryCount); ReconnectionRetryCount--; //On 5 failed reconnections exit if (ReconnectionRetryCount == 0) throw; _serviceProxy = cm.connect(connection); service = (IOrganizationService)_serviceProxy; LogManager.WriteLog("Error:The CRM authentication session expired."); totalImportFailures++; importFailuresForEntity++; ImportFailure failure = new ImportFailure { CreatedOn = DateTime.Now.ToString(), EntityName = ee.EntityName, Operation = executingOperation, Reason = ex.InnerException.Message, Url = profile.getSourceConneciton().ServerAddress + "main.aspx?pagetype=entityrecord&etn=" + ee.EntityName + "&id=" + entity.Id.ToString() }; report.TotalImportFailures += 1; //Insert the Failure line in the Failures Report WriteNewImportFailureLine(failure, importFailuresReportFileName); } else { throw; } } totalTreatedRecords++; treatedRecordsForEntity++; updateTransportReport(report, ee, importedRecordsForEntity, importFailuresForEntity, entityImportStartDT); } } } LogManager.WriteLog("Treated " + treatedRecordsForEntity + " " + ee.EntityName + " records with " + importedRecordsForEntity + " successfully imported records and " + importFailuresForEntity + " failures."); } TimeSpan importTimeSpan = DateTime.Now - importStartDT; LogManager.WriteLog("Import finished for " + connection.ConnectionName + ". Treated " + totalTreatedRecords + " records in " + importTimeSpan.ToString().Substring(0, 10) + ". Successfuly imported " + totalImportSuccess + " records and " + totalImportFailures + " failures."); //WriteTransportReport(report, transportReportFileName); } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { LogManager.WriteLog("Error:" + ex.Detail.Message + "\n" + ex.Detail.TraceText); } catch (Exception ex) { if (ex.InnerException != null) LogManager.WriteLog("Error:" + ex.Message + "\n" + ex.InnerException.Message); else { LogManager.WriteLog("Error:" + ex.Message); } } }
/// <summary> /// Exports the specified profile. /// </summary> /// <param name="profile">The profile.</param> /// <param name="transportReportFileName">Name of the transport report file.</param> private void Export(TransportationProfile profile, string transportReportFileName) { try { TransportReport report = new TransportReport(transportReportFileName); //Get Transport Report if (File.Exists(transportReportFileName)) { report = ReadTransportReport(transportReportFileName); } //Clean Data folder string dataExportFolder = Folder + "\\" + profile.ProfileName + "\\Data"; if (Directory.Exists(dataExportFolder)) { Directory.Delete(dataExportFolder, true); } Directory.CreateDirectory(dataExportFolder); MSCRMConnection connection = profile.getSourceConneciton(); EnvStructure es = ReadEnvStructure(profile.SourceConnectionName); _serviceProxy = cm.connect(connection); IOrganizationService service = (IOrganizationService)_serviceProxy; List<TransportReportLine> TransportReport = new List<TransportReportLine>(); profile.TotalExportedRecords = 0; //Mesure export time DateTime exportStartDT = DateTime.Now; LogManager.WriteLog("Start exporting data from " + connection.ConnectionName); int recordCount = 0; if (es != null) { //Order export according to profile's transport order IOrderedEnumerable<SelectedEntity> orderedSelectedEntities = profile.SelectedEntities.OrderBy(se => se.TransportOrder); foreach (SelectedEntity ee in orderedSelectedEntities) { LogManager.WriteLog("Exporting data for entity " + ee.EntityName); DateTime entityExportStartDT = DateTime.Now; string fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"; fetchXml += "<entity name='" + ee.EntityName + "'>"; //Get Entity structure EnvEntity strE = new EnvEntity(); foreach (EnvEntity envE in es.Entities) { if (envE.EntityName == ee.EntityName) { strE = envE; break; } } //Create fetchXML Query foreach (string ea in strE.Attributes) { if (ee.IgnoredAttributes == null) { fetchXml += "<attribute name='" + ea + "' />"; } else if (!ee.IgnoredAttributes.Contains(ea)) { fetchXml += "<attribute name='" + ea + "' />"; } } //Add Query filter fetchXml += ee.Filter; fetchXml += "</entity></fetch>"; int recordCountPerEntity = ExportEntity(profile, fetchXml); recordCount += recordCountPerEntity; DateTime entityExportEndDT = DateTime.Now; TimeSpan ts = entityExportEndDT - entityExportStartDT; TransportReportLine transportReportLine = new TransportReportLine(); transportReportLine.Entity = ee.EntityName; transportReportLine.ExportedRecords = recordCountPerEntity; report.TotalExportedRecords += recordCountPerEntity; transportReportLine.ExportedIn = ts.ToString().Substring(0, 10); transportReportLine.ExportStartedAt = entityExportStartDT.ToString(); transportReportLine.ExportFinishedAt = entityExportEndDT.ToString(); report.ReportLines.Add(transportReportLine); WriteTransportReport(report, transportReportFileName); } } TimeSpan exportTimeSpan = DateTime.Now - exportStartDT; LogManager.WriteLog("Export finished for " + profile.SourceConnectionName + ". Exported " + recordCount + " records in " + exportTimeSpan.ToString().Substring(0, 10)); } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { LogManager.WriteLog("Error:" + ex.Detail.Message + "\n" + ex.Detail.TraceText); } catch (Exception ex) { if (ex.InnerException != null) { LogManager.WriteLog("Error:" + ex.Message + "\n" + ex.InnerException.Message); } else { LogManager.WriteLog("Error:" + ex.Message); } } }
/// <summary> /// Updates the profile. /// </summary> /// <param name="profile">The profile.</param> public void UpdateProfile(TransportationProfile profile) { if (!Directory.Exists(Folder + "\\" + profile.ProfileName)) Directory.CreateDirectory(Folder + "\\" + profile.ProfileName); //Refresh Transportation Profiles in case some other instance is updating the profiles ReadProfiles(); for (int i = 0; i < Profiles.Count; i++) { if (Profiles[i].ProfileName == profile.ProfileName) { Profiles[i] = profile; break; } } WriteProfiles(); }
/// <summary> /// Exports the specified profile. /// </summary> /// <param name="profile">The profile.</param> /// <param name="transportReportFileName">Name of the transport report file.</param> private void Export(TransportationProfile profile, string transportReportFileName) { try { TransportReport report = new TransportReport(transportReportFileName); //Get Transport Report if (File.Exists(transportReportFileName)) { report = ReadTransportReport(transportReportFileName); } //Clean Data folder string dataExportFolder = Folder + "\\" + profile.ProfileName + "\\Data"; if (Directory.Exists(dataExportFolder)) { Directory.Delete(dataExportFolder, true); } Directory.CreateDirectory(dataExportFolder); MSCRMConnection connection = profile.getSourceConneciton(); EnvStructure es = ReadEnvStructure(profile.SourceConnectionName); _serviceProxy = cm.connect(connection); IOrganizationService service = (IOrganizationService)_serviceProxy; List <TransportReportLine> TransportReport = new List <TransportReportLine>(); profile.TotalExportedRecords = 0; //Mesure export time DateTime exportStartDT = DateTime.Now; LogManager.WriteLog("Start exporting data from " + connection.ConnectionName); int recordCount = 0; if (es != null) { //Order export according to profile's transport order IOrderedEnumerable <SelectedEntity> orderedSelectedEntities = profile.SelectedEntities.OrderBy(se => se.TransportOrder); foreach (SelectedEntity ee in orderedSelectedEntities) { LogManager.WriteLog("Exporting data for entity " + ee.EntityName); DateTime entityExportStartDT = DateTime.Now; string fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"; fetchXml += "<entity name='" + ee.EntityName + "'>"; //Get Entity structure EnvEntity strE = new EnvEntity(); foreach (EnvEntity envE in es.Entities) { if (envE.EntityName == ee.EntityName) { strE = envE; break; } } //Create fetchXML Query foreach (string ea in strE.Attributes) { if (ee.IgnoredAttributes == null) { fetchXml += "<attribute name='" + ea + "' />"; } else if (!ee.IgnoredAttributes.Contains(ea)) { fetchXml += "<attribute name='" + ea + "' />"; } } //Add Query filter fetchXml += ee.Filter; fetchXml += "</entity></fetch>"; int recordCountPerEntity = ExportEntity(profile, fetchXml); recordCount += recordCountPerEntity; DateTime entityExportEndDT = DateTime.Now; TimeSpan ts = entityExportEndDT - entityExportStartDT; TransportReportLine transportReportLine = new TransportReportLine(); transportReportLine.Entity = ee.EntityName; transportReportLine.ExportedRecords = recordCountPerEntity; report.TotalExportedRecords += recordCountPerEntity; transportReportLine.ExportedIn = ts.ToString().Substring(0, 10); transportReportLine.ExportStartedAt = entityExportStartDT.ToString(); transportReportLine.ExportFinishedAt = entityExportEndDT.ToString(); report.ReportLines.Add(transportReportLine); WriteTransportReport(report, transportReportFileName); } } TimeSpan exportTimeSpan = DateTime.Now - exportStartDT; LogManager.WriteLog("Export finished for " + profile.SourceConnectionName + ". Exported " + recordCount + " records in " + exportTimeSpan.ToString().Substring(0, 10)); } catch (FaultException <Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { LogManager.WriteLog("Error:" + ex.Detail.Message + "\n" + ex.Detail.TraceText); } catch (Exception ex) { if (ex.InnerException != null) { LogManager.WriteLog("Error:" + ex.Message + "\n" + ex.InnerException.Message); } else { LogManager.WriteLog("Error:" + ex.Message); } } }
private bool SaveProfile() { bool result = true; //Check that all fields are provided if (string.IsNullOrEmpty(textBoxTransportationProfileName.Text)) { MessageBox.Show("Transportation Profile Name is mandatory!"); return false; } //Check that the name of te connection is valid if (textBoxTransportationProfileName.Text.Contains(" ") || textBoxTransportationProfileName.Text.Contains("\\") || textBoxTransportationProfileName.Text.Contains("/") || textBoxTransportationProfileName.Text.Contains(">") || textBoxTransportationProfileName.Text.Contains("<") || textBoxTransportationProfileName.Text.Contains("?") || textBoxTransportationProfileName.Text.Contains("*") || textBoxTransportationProfileName.Text.Contains(":") || textBoxTransportationProfileName.Text.Contains("|") || textBoxTransportationProfileName.Text.Contains("\"") || textBoxTransportationProfileName.Text.Contains("'") ) { MessageBox.Show("You shouldn't use spaces nor the following characters (\\/<>?*:|\"') in the Transportation Profile Name as it will be used to create folders and files."); return false; } if (comboBoxConnectionSource.SelectedItem == null) { MessageBox.Show("You must select a Source for the Profile"); return false; } if (comboBoxConnectionTarget.SelectedItem == null && comboBoxOperation.SelectedItem.ToString() != "Export Data") { MessageBox.Show("You must select a Target for the Profile"); return false; } //Check for Transport Order Conflicts foreach (ComboBox cb in panelTransportOrder.Controls.OfType<ComboBox>()) { int numberOfOccurencies = 0; int currentComboSelectedIndex = cb.SelectedIndex; foreach (ComboBox cb1 in panelTransportOrder.Controls.OfType<ComboBox>()) { if (currentComboSelectedIndex == cb1.SelectedIndex) { numberOfOccurencies++; } if (numberOfOccurencies > 1) { MessageBox.Show("The entity \"" + cb.SelectedItem + "\" is declared more than once int the Transport Order. Fix this before saving."); return false; } } } //Check if this is a creation if (currentProfile == null) { //Check if a Connection having the same name exist already foreach (TransportationProfile tp in man.Profiles) { if (tp.ProfileName.ToLower() == textBoxTransportationProfileName.Text.ToLower()) { MessageBox.Show("Transportation Profile with the name " + textBoxTransportationProfileName.Text + " exist already. Please select another name"); return false; } } TransportationProfile newProfile = new TransportationProfile(); newProfile.ProfileName = textBoxTransportationProfileName.Text; newProfile.ImportMode = comboBoxImportMode.SelectedIndex; newProfile.SourceConnectionName = comboBoxConnectionSource.SelectedItem.ToString(); newProfile.setSourceConneciton(); if (comboBoxOperation.SelectedItem.ToString() != "Export Data") { newProfile.TargetConnectionName = comboBoxConnectionTarget.SelectedItem.ToString(); newProfile.setTargetConneciton(); } newProfile.SelectedEntities = new List<SelectedEntity>(); foreach (string checkedEntity in checkedListBoxEntities.CheckedItems) { SelectedEntity ee = new SelectedEntity(); ee.EntityName = checkedEntity; ee.ExportedRecords = 0; foreach (ComboBox cb in panelTransportOrder.Controls.OfType<ComboBox>()) { if (cb.SelectedItem.ToString() == ee.EntityName) { ee.TransportOrder = (int)cb.Tag; break; } } SelectedEntity seForIgnoredAttributes = TemporarySelectedEntityListForIgnoredAttributes.Find(match => match.EntityName == checkedEntity); if (seForIgnoredAttributes != null) { ee.IgnoredAttributes = seForIgnoredAttributes.IgnoredAttributes; ee.Filter = seForIgnoredAttributes.Filter; } newProfile.SelectedEntities.Add(ee); } newProfile.Operation = comboBoxOperation.SelectedIndex; man.CreateProfile(newProfile); comboBoxTransportationProfiles.Items.AddRange(new object[] { newProfile.ProfileName }); comboBoxTransportationProfiles.SelectedItem = newProfile.ProfileName; } else { currentProfile.ProfileName = textBoxTransportationProfileName.Text; currentProfile.ImportMode = comboBoxImportMode.SelectedIndex; currentProfile.SourceConnectionName = comboBoxConnectionSource.SelectedItem.ToString(); currentProfile.setSourceConneciton(); if (comboBoxOperation.SelectedItem.ToString() != "Export Data") { currentProfile.TargetConnectionName = comboBoxConnectionTarget.SelectedItem.ToString(); currentProfile.setTargetConneciton(); } //Backup Export Records numbers if existing List<SelectedEntity> backupSelectedEntites = currentProfile.SelectedEntities; currentProfile.SelectedEntities = new List<SelectedEntity>(); TransportationProfile oldProfile = man.GetProfile(currentProfile.ProfileName); foreach (string checkedEntity in checkedListBoxEntities.CheckedItems) { SelectedEntity ee = currentProfile.getSelectedEntity(checkedEntity); if (ee == null) { ee = new SelectedEntity(); ee.EntityName = checkedEntity; //Restore Export Records numbers if existing SelectedEntity tse = backupSelectedEntites.Find(b => b.EntityName == checkedEntity); if (tse != null && tse.ExportedRecords > 0) { ee.ExportedRecords = tse.ExportedRecords; } else { ee.ExportedRecords = 0; } foreach (ComboBox cb in panelTransportOrder.Controls.OfType<ComboBox>()) { if (cb.SelectedItem.ToString() == ee.EntityName) { ee.TransportOrder = (int)cb.Tag; break; } } SelectedEntity seForIgnoredAttributes = TemporarySelectedEntityListForIgnoredAttributes.Find(match => match.EntityName == checkedEntity); if (seForIgnoredAttributes != null) { ee.IgnoredAttributes = seForIgnoredAttributes.IgnoredAttributes; ee.Filter = seForIgnoredAttributes.Filter; } currentProfile.SelectedEntities.Add(ee); } else { foreach (ComboBox cb in panelTransportOrder.Controls.OfType<ComboBox>()) { if (cb.SelectedItem.ToString() == ee.EntityName) { ee.TransportOrder = (int)cb.Tag; break; } } } } //Records mapping cleanup if (currentProfile.RecordMappings != null) { List<int> RecordMappingsForRemovalIndexes = new List<int>(); for (int i = 0; i < currentProfile.RecordMappings.Count; i++) { if (currentProfile.RecordMappings[i].SourceRecordId == Guid.Empty && currentProfile.RecordMappings[i].TargetRecordId == Guid.Empty) RecordMappingsForRemovalIndexes.Add(i); } for (int removeIndex = RecordMappingsForRemovalIndexes.Count - 1; removeIndex >= 0; removeIndex--) currentProfile.RecordMappings.RemoveAt(removeIndex); if (currentProfile.RecordMappings.Count == 0) currentProfile.RecordMappings = null; } currentProfile.Operation = comboBoxOperation.SelectedIndex; man.UpdateProfile(currentProfile); } runProfileToolStripMenuItem.Enabled = true; toolStripStatusLabel.Text = "Transportation Profile " + currentProfile.ProfileName + " saved."; LogManager.WriteLog("Transportation Profile " + currentProfile.ProfileName + " saved."); return result; }
private void comboBoxTransportationProfiles_SelectedIndexChanged(object sender, EventArgs e) { comboBoxConnectionSource.SelectedItem = null; comboBoxConnectionTarget.SelectedItem = null; if (comboBoxTransportationProfiles.SelectedItem != null) { currentProfile = man.Profiles[comboBoxTransportationProfiles.SelectedIndex]; textBoxTransportationProfileName.Text = currentProfile.ProfileName; comboBoxImportMode.SelectedIndex = currentProfile.ImportMode; comboBoxConnectionSource.SelectedItem = currentProfile.SourceConnectionName; comboBoxConnectionTarget.SelectedItem = currentProfile.TargetConnectionName; TemporarySelectedEntityListForIgnoredAttributes = currentProfile.SelectedEntities; deleteProfileToolStripMenuItem.Enabled = true; textBoxTransportationProfileName.Enabled = false; comboBoxOperation.SelectedIndex = currentProfile.Operation; runProfileToolStripMenuItem.Enabled = true; } else { currentProfile = null; textBoxTransportationProfileName.Text = ""; comboBoxOperation.SelectedIndex = 2; comboBoxImportMode.SelectedIndex = 1; deleteProfileToolStripMenuItem.Enabled = false; textBoxTransportationProfileName.Enabled = true; labelStructureLastLoadedDate.Text = "never"; runProfileToolStripMenuItem.Enabled = false; } }
private static void Main(string[] args) { //Set the application directory as the current directory string appPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); appPath = appPath.Replace("file:\\", ""); Directory.SetCurrentDirectory(appPath); MSCRMTransportationProfilesManager man = new MSCRMTransportationProfilesManager(); string selectedTransportationProfileName = ""; if (args.Length == 0) { if (man.Profiles.Count == 0) { Console.WriteLine("\nNo profiles found."); return; } //Display all profiles for selection Console.WriteLine("\nSpecify the Profile to run (1-{0}) [1] : ", man.Profiles.Count); int tpCpt = 1; foreach (TransportationProfile profile in man.Profiles) { Console.WriteLine(tpCpt + ". " + profile.ProfileName); tpCpt++; } String input = Console.ReadLine(); if (input == String.Empty) { input = "1"; } int tpNumber; Int32.TryParse(input, out tpNumber); if (tpNumber > 0 && tpNumber <= man.Profiles.Count) { selectedTransportationProfileName = man.Profiles[tpNumber - 1].ProfileName; } else { Console.WriteLine("The specified does not exist."); return; } } else { //Check that the Profile name is provided if (string.IsNullOrEmpty(args[0])) { return; } selectedTransportationProfileName = args[0]; } TransportationProfile p = man.GetProfile(selectedTransportationProfileName); if (p == null) { Console.WriteLine("The specified Profile does not exist."); return; } man.RunProfile(p); }