๐Ÿ” CVN XrmToolBox Record Compare 2

Compare records between Dynamics 365 environments with detailed insights

๐Ÿ“‹ Project Overview

CVN.XrmToolBox.RecordCompare2 is an XrmToolBox plugin designed to compare records between two Dynamics 365/Dataverse environments. It provides detailed insights into differences between source and target organizations, helping identify mismatches, duplications, and missing records.

โญ Features

Core Capabilities

Record Count Comparison

Quickly identify if source and target have matching record counts

Field-Level Comparison

Compare individual field values across matched records

Bidirectional Analysis

Compare sourceโ†’target and targetโ†’source to catch all discrepancies

Note/Attachment Comparison

Validate notes and attachments are identical

Smart Filtering

Filter by website, creation date, custom expressions, and linked parents

Report Generation

Save comparison results with detailed mismatch files

Supported Models

  • Standard Model: Uses direct link entities for parent filtering
  • Enhanced Model: Uses in-memory joins for virtual table support

๐Ÿ”ง Installation & Setup

Prerequisites

  • XrmToolBox (latest version)
  • Access to source and target Dynamics 365/Dataverse environments
  • Administrative permissions in both environments

Installation Steps

  1. Download the plugin DLL: CVN.XRMTOOLBOX.RECORDCOMPARE.dll
  2. Place in XrmToolBox plugins folder: %APPDATA%\Roaming\MscrmTools\XrmToolBox\Plugins
  3. Restart XrmToolBox
  4. Plugin will appear in the Tools menu

Initial Configuration

  1. Open the plugin in XrmToolBox
  2. Configure in Settings:
    • Result Folder: Where comparison reports are saved
    • XML Configuration: Select or create entity comparison config
    • Extension Prefix: Custom prefix for extended fields (e.g., "adx" for Portal)
    • Enhanced Model: Enable for virtual tables
    • Compare Tool Directory: Path to diff/merge tool
    • Dev Env Directory: Path to Visual Studio (optional)

โš™๏ธ Configuration Guide

XML Configuration Structure

The configuration file defines which entities to compare and how:

<?xml version="1.0" encoding="utf-8"?> <ViewModel> <EntityList> <CompareEntity> <EntityName>mspp_entityformmetadata</EntityName> <Name>Entity Form Metadata</Name> <NotLinkedToSite>false</NotLinkedToSite> <Keys> <Key> <Name>adx_name</Name> <DisplayName>Name</DisplayName> </Key> </Keys> </CompareEntity> </EntityList> </ViewModel>

Configuration Elements

Element Description
EntityName Logical name of the entity to compare
Name Display name for UI
NotLinkedToSite If false, filters by website ID
ParentLinkedToSite If true, parent records must be in same site
IntersectEntity Set true for intersection/junction entities
CompareNotes If true, compares notes/attachments
Keys Fields used to match records between environments
LinkedEntityKey Foreign key field in linked entity
LinkedEntityName Name of the linked entity
LinkedFieldName Field to retrieve from linked entity

Excluded Fields Configuration

Define fields to skip during comparison (e.g., system fields, timestamps):

<?xml version="1.0" encoding="utf-8"?> <ArrayOfString> <string>createdon</string> <string>modifiedon</string> <string>createdby</string> <string>modifiedby</string> <string>versionnumber</string> </ArrayOfString>

๐Ÿš€ Usage Guide

  1. Select Target Organization
    • Click "Select Target" button
    • Choose your target environment connection
    • Verify connection details
  2. Select Entities to Compare
    • Check the entities you want to compare from the entity list
    • Use "Select All" to compare all configured entities
  3. Configure Filters (Optional)
    • Website/Site: Select from dropdown
    • Created On: Check box and select date to filter by creation date
    • Custom filters via XML configuration
  4. Run Comparison
    • Click "Run" or "Process" button
    • Monitor progress in the status bar
    • Wait for comparison to complete
  5. Review Results
    • Results appear in the grid showing Type, Entity, Key, Field, V1/V2 values, and Direction
    • Large field values are saved to files for comparison
    • Use integrated diff tool to visualize changes

๐Ÿ“Š Data Models

CompareResult

public class CompareResult { public string EntityName { get; set; } public int Count1 { get; set; } // Source count public int Count2 { get; set; } // Target count public bool IsCountOK { get; set; } // Counts match public List<ResultLog> ResultLogs { get; set; } }

ResultLog

public class ResultLog { public string EntityName { get; set; } public string EntityDisplayName { get; set; } public ResultLogTypes Type { get; set; } public string Key { get; set; } // Record identifier public string Field { get; set; } public string V1 { get; set; } // Source value public string V2 { get; set; } // Target value public string Direction { get; set; } // 1 or 2 public string V1_Details { get; set; } // File path for large values public string V2_Details { get; set; } }

Result Types

  • CountMismatch - Different record counts
  • NotFound - Record exists in source but not target
  • Duplication - Multiple matching records in target
  • Mismatch - Field value differs
  • NotesCount - Different number of notes
  • EmptyKey - Key field is null
  • FilesizeMismatch - Note attachment size differs
  • NoDifference - No differences found

๐ŸŽฏ Advanced Features

Linked Entity Matching

Match records by related entity fields (e.g., match by Form Name instead of ID):

<Key> <Name>mspp_entityformid</Name> <LinkedEntityKey>mspp_entityformid</LinkedEntityKey> <LinkedEntityName>mspp_entityform</LinkedEntityName> <LinkedFieldName>adx_name</LinkedFieldName> </Key>

Parent Record Filtering

Filter child records by parent's website:

<ParentLinkedToSite>true</ParentLinkedToSite> <ParentTableName>mspp_website</ParentTableName> <ParentKeyName>mspp_websiteid</ParentKeyName> <LinkKeyName>mspp_websiteid</LinkKeyName>

File Comparison

Large field values (>40 characters) are automatically saved to files:

  • JSON files: Auto-formatted for readability
  • HTML files: Detected and formatted
  • XML files: Detected and preserved
  • Text files: Plain text comparison

๐Ÿ› Troubleshooting

Issue: "No results found" or empty comparison

Solutions:
  • Verify website selection is correct
  • Check if date filter is excluding records
  • Ensure entities are configured in XML
  • Verify entity permissions in both environments

Issue: Service connection fails

Solutions:
  • Test connection with basic retrieve query
  • Check network connectivity
  • Verify authentication credentials
  • Review debug output window

Issue: Virtual table comparison shows different counts

Solutions:
  • Enable "Enhanced Model" in settings
  • Ensure ParentLinkedToSite is configured correctly
  • Check parent records exist in target environment

Issue: Notes comparison fails

Solutions:
  • Verify CompareNotes is enabled in config
  • Check annotation records have filenames
  • Ensure file paths are accessible

๐Ÿ“ Output & Reports

Result Files

Comparison results are saved to the configured Result Folder:

  • Large field values saved with format-specific extensions (.json, .xml, .html, etc.)
  • File naming: {RecordId}_{Step}_{Service}.{ext}
  • Example: 550e8400_1_1.json

Viewing Results

  1. In-Application: Browse grid in plugin
  2. File System: Open Result Folder
  3. Diff Tool: Right-click โ†’ Open with configured comparison tool

โšก Performance Considerations

Large Datasets

  • Tool loads results in-memory for filtering
  • Recommended limit: 5,000 records per entity
  • For larger sets: Use date filters or custom filters

Optimization Tips

  1. Filter by creation date to reduce scope
  2. Use specific keys for matching (avoid generic fields)
  3. Exclude unnecessary fields
  4. Disable note comparison if not needed
  5. Run during off-peak hours

๐Ÿ“š Configuration Examples

Example 1: Portal Entities (Standard Model)

<CompareEntity> <EntityName>adx_webpage</EntityName> <Name>Web Pages</Name> <NotLinkedToSite>false</NotLinkedToSite> <Keys> <Key> <Name>adx_name</Name> <DisplayName>Name</DisplayName> </Key> </Keys> </CompareEntity>

Example 2: Linked Records with Parent Filter

<CompareEntity> <EntityName>adx_webform</EntityName> <Name>Web Forms</Name> <ParentLinkedToSite>true</ParentLinkedToSite> <ParentTableName>adx_website</ParentTableName> <Keys> <Key> <Name>adx_name</Name> <DisplayName>Name</DisplayName> </Key> </Keys> </CompareEntity>
โ†‘