/// <summary>
        ///     Load entities.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override IEnumerable <EntityEntry> GetEntities(IProcessingContext context)
        {
            /////
            // Query entities that are part of the solution
            /////
            const string sql = @"
DECLARE @name UNIQUEIDENTIFIER
DECLARE @isOfType UNIQUEIDENTIFIER

SELECT @name = EntityUid FROM AppData_Alias WHERE Data = 'name' AND Namespace = 'core'
SELECT @isOfType = EntityUid FROM AppData_Alias WHERE Data = 'isOfType' AND Namespace = 'core'

SELECT DISTINCT e.EntityUid, en.Data, etn.Data
FROM AppEntity e
LEFT JOIN AppData_NVarChar en ON e.EntityUid = en.EntityUid AND e.AppVerUid = en.AppVerUid AND en.FieldUid = @name
LEFT JOIN AppRelationship et ON e.EntityUid = et.FromUid AND e.AppVerUid = et.AppVerUid AND et.TypeUid = @isOfType
LEFT JOIN AppData_NVarChar etn ON et.ToUid = etn.EntityUid AND etn.FieldUid = @name
WHERE e.AppVerUid = @appVer";

            var map = new Dictionary <Guid, EntityStagingEntry>( );

            using (IDbCommand command = CreateCommand( ))
            {
                command.CommandText = sql;
                command.AddParameterWithValue("@appVer", AppVerId);

                using (IDataReader reader = command.ExecuteReader( ))
                {
                    if (reader != null)
                    {
                        while (reader.Read( ))
                        {
                            if (reader.IsDBNull(0))
                            {
                                context.WriteWarning("Unexpected null UpgradeId in Entity.");
                                continue;
                            }

                            EntityStagingEntry entry;

                            if (!map.TryGetValue(reader.GetGuid(0), out entry))
                            {
                                entry = new EntityStagingEntry
                                {
                                    EntityId       = reader.GetGuid(0),
                                    EntityName     = reader.IsDBNull(1) ? null : reader.GetString(1),
                                    EntityTypeName = reader.IsDBNull(2) ? null : reader.GetString(2)
                                };

                                map[entry.EntityId] = entry;
                            }
                            else
                            {
                                if (entry.EntityTypeName != null && !reader.IsDBNull(2))
                                {
                                    string[] split = entry.EntityTypeName.Split(new[]
                                    {
                                        ','
                                    });

                                    string type = reader.GetString(2);

                                    if (split.All(s => s.Trim( ).ToLowerInvariant( ) != type))
                                    {
                                        entry.EntityTypeName += ", " + type;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(map.Values);
        }
        /// <summary>
        ///     Load entities.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        IEnumerable <EntityEntry> IDataSource.GetEntities(IProcessingContext context)
        {
            if (_entityCache == null)
            {
                var data = new Dictionary <Guid, EntityEntry>( );

                /////
                // Query entities that are part of the solution
                /////
                using (IDbCommand command = CreateCommand( ))
                {
                    command.CommandText = "spGetTenantAppStagedEntities";
                    command.CommandType = CommandType.StoredProcedure;
                    command.AddParameterWithValue("@solutionId", SolutionId);
                    command.AddParameterWithValue("@tenant", TenantId);

                    using (IDataReader reader = command.ExecuteReader( ))
                    {
                        while (reader.Read( ))
                        {
                            if (reader.IsDBNull(0))
                            {
                                context?.WriteWarning("Unexpected null UpgradeId in Entity.");

                                continue;
                            }

                            int    depth           = reader.GetInt32(0);
                            Guid   entityUpgradeId = reader.GetGuid(1);
                            long   entityId        = reader.GetInt64(2);
                            string entityName      = reader.IsDBNull(3) ? null : reader.GetString(3);
                            long   entityTypeId    = reader.IsDBNull(4) ? 0 : reader.GetInt64(4);
                            string entityTypeName  = reader.IsDBNull(5) ? null : reader.GetString(5);

                            EntityEntry entry;

                            if (!data.TryGetValue(entityUpgradeId, out entry))
                            {
                                entry = new EntityStagingEntry
                                {
                                    EntityId       = entityUpgradeId,
                                    Id             = entityId,
                                    EntityName     = entityName,
                                    EntityTypeId   = entityTypeId,
                                    EntityTypeName = entityTypeName
                                };

                                data[entityUpgradeId] = entry;
                            }

                            var castEntry = entry as EntityStagingEntry;

                            if (depth > 0 && castEntry != null)
                            {
                                if (castEntry.Parents == null)
                                {
                                    castEntry.Parents = new List <EntityParentEntry>( );
                                }

                                castEntry.Parents.Add(new EntityParentEntry
                                {
                                    Depth = depth,
                                    ParentEntityUpgradeId     = reader.GetGuid(6),
                                    RelationshipTypeUpgradeId = reader.GetGuid(7),
                                    RelationshipTypeId        = reader.IsDBNull(8) ? 0 : reader.GetInt64(8),
                                    RelationshipTypeName      = reader.IsDBNull(9) ? null : reader.GetString(9),
                                    Reason = ( InclusionReason )Enum.Parse(typeof(InclusionReason), reader.GetString(10), true),
                                });
                            }
                        }
                    }
                }

                _entityCache = data.Values.ToList( );
            }

            return(_entityCache);
        }