private void QueryRelationshipMetadata()
        {
            WorkAsync("Querying Relationships for Selected Entity: " + entityDropdown.SelectedValue,
                e => // Work To Do Asynchronously
                {
                    var request = new RetrieveAllEntitiesRequest
                    {
                        EntityFilters = EntityFilters.Relationships,
                        RetrieveAsIfPublished = true
                    };

                   e.Result = Service.Execute(request);
                }, e =>
                {
                    var reader = new EntityMetadataReader(e.Result as OrganizationResponse);
                    relationShipDropdown.DataSource = reader.ParseRelationships(entityDropdown.SelectedValue as string);

                    var formUpdater = new GridUpdater(entityAttributeView)
                    {
                        ColumnForAttributeName = "Logical Name",
                        ColumnForAttributeType = "Attribute Type"
                    };
                    formUpdater.Where(row => row[formUpdater.ColumnForAttributeType] as string == "Lookup")
                        .ForEach(x => formUpdater.OverwriteAttributeTypeWithRelationshipInfo(x, reader));
                    formUpdater.Refresh();
                });
        }
        private void UpdateRelatedRecords()
        {
            WorkAsync("Updating Related Records...",
                (w, e) => // Work To Do Asynchronously
                {
                    w.ReportProgress(0, "Parsing Selected Surviving Record");

                    // Uncheck Selected Record from the To Be Deleted List
                    var formReader = new FormEntryReader(null);
                    var selectedEntityRecordFromStep5 = formReader.GetSelectedRowItem(entityRecordGrid);
                    selectedEntityRecordFromStep5["Mark for Deletion"] = false;
                    entityRecordGrid.Refresh();

                    // Get RelatedEntityValues
                    var entitySelected = formReader.ReadEntitySelected(entityDropdown);
                    formReader.ReadRelatedEntitySelected(relationShipDropdown);
                    var relatedEntityPkName = formReader.ReferencingEntityName + "id";
                    var relatedEntity = formReader.ReferencingEntityName;
                    var linkColumnOnRelatedEntity = formReader.ReferencingAttributeName;

                    var formUpdater = new GridUpdater(relatedEntityGrid);
                    formUpdater.Where(row => row[relatedEntityPkName] is Guid)
                        .ForEach(row =>
                        {
                            var currentRow = row.Table.Rows.IndexOf(row) + 1;
                            // TO DO: The indexing totals system can be improved to cover actual work rows
                            var totalRows = row.Table.Rows.Count;
                            w.ReportProgress(currentRow / totalRows, "Updating Row ID: " + currentRow);
                            var updateItem = new Entity(relatedEntity) {Id = (Guid) row[relatedEntityPkName]};
                            updateItem[linkColumnOnRelatedEntity] = new EntityReference(
                                entitySelected,
                                (Guid)selectedEntityRecordFromStep5[entitySelected + "id"]);
                            Service.Update(updateItem);
                            row["Updated"] = true;
                        });
                    w.ReportProgress(99, "Finishing");
                    formUpdater.Refresh();

                    e.Result = "Update Complete";
                },
                e => // Finished Async Call.  Cleanup
                    MessageBox.Show(e.Result as string),
                e => // Logic wants to display an update.  This gets called when ReportProgress Gets Called
                    SetWorkingMessage(e.UserState.ToString()));
        }
        private void DeleteMarkedRecords()
        {
            WorkAsync("Deleting Marked Records...",
                (w, e) => // Work To Do Asynchronously
                {
                    var formReader = new FormEntryReader(null);
                    var entitySelected = formReader.ReadEntitySelected(entityDropdown);

                    w.ReportProgress(0, "Start Parsing");
                    var formUpdater = new GridUpdater(entityRecordGrid);
                    formUpdater.Where(row => (bool) row["Mark for Deletion"])
                        .ForEach(row =>
                        {
                            var currentRow = row.Table.Rows.IndexOf(row) + 1;
                            // TO DO: The indexing totals system can be improved to cover actual work rows
                            var totalRows = row.Table.Rows.Count;
                            w.ReportProgress(currentRow / totalRows, "Deleting Row ID: " + currentRow);
                            Service.Delete(entitySelected, (Guid)row[entitySelected+"id"]);
                        });
                    w.ReportProgress(99, "Finishing");
                    formUpdater.Refresh();

                    // Populate whatever the results that need to be returned to the Results Property
                    e.Result = "Deletion Complete";
                },
                e => // Finished Async Call.  Cleanup
                    MessageBox.Show(e.Result as string),
                e => // Logic wants to display an update.  This gets called when ReportProgress Gets Called
                    SetWorkingMessage(e.UserState.ToString()));
        }