private void BuildAttributes(EntityCacheItem entityCacheItem)
 {
     Logger.Debug($"Building attributes for '{entityCacheItem.CkId}'");
     foreach (var cacheItem in entityCacheItem.GetBaseTypesChain(false))
     {
         foreach (var attribute in cacheItem.Attributes)
         {
             if (!entityCacheItem.Attributes.ContainsKey(attribute.Key))
             {
                 entityCacheItem.Attributes.Add(attribute.Key, attribute.Value);
             }
         }
     }
 }
        private void BuildInheritanceGraph(CkTypeInfo ckTypeInfo, EntityCacheItem entityCacheItem)
        {
            Logger.Debug($"Building inheritance graph '{entityCacheItem.CkId}'");

            foreach (var ckBaseTypeInfo in ckTypeInfo.BaseTypes)
            {
                if (ckBaseTypeInfo.OriginCkId == entityCacheItem.CkId)
                {
                    continue;
                }

                Logger.Debug($"Building inheritance graph '{entityCacheItem.CkId}', base type {ckBaseTypeInfo.OriginCkId}");
                var baseType = _metaCache[ckBaseTypeInfo.OriginCkId];
                if (ckBaseTypeInfo.TargetCkId == entityCacheItem.CkId)
                {
                    entityCacheItem.BaseType = baseType;
                }

                baseType.DerivedTypes.Add(entityCacheItem);
            }
        }
        public async Task Initialize(IDatabaseContext databaseContext)
        {
            if (_isInitialized)
            {
                return;
            }

            Logger.Debug($"Initializing MetaCache");

            var session = await databaseContext.StartSessionAsync();

            session.StartTransaction();

            var ckTypeInfosDictionary = (await databaseContext.GetCkTypeInfoAsync(session)).ToDictionary(k => k.CkId, v => v);

            foreach (var ckTypeInfo in ckTypeInfosDictionary.Values)
            {
                var entityCacheItem = new EntityCacheItem(ckTypeInfo);

                foreach (var attribute in ckTypeInfo.Attributes)
                {
                    var ckAttribute =
                        await databaseContext.CkAttributes.FindSingleOrDefaultAsync(session, a =>
                                                                                    a.AttributeId == attribute.AttributeId);

                    entityCacheItem.Attributes.Add(attribute.AttributeName,
                                                   new AttributeCacheItem(attribute.AttributeName, attribute, ckAttribute));
                }

                if (ckTypeInfo.TextSearchLanguages != null)
                {
                    foreach (var textSearchLanguage in ckTypeInfo.TextSearchLanguages)
                    {
                        var textSearchCacheItem = new TextSearchLanguageCacheItem(textSearchLanguage.Language);

                        foreach (var textSearchField in textSearchLanguage.Fields)
                        {
                            textSearchCacheItem.Fields.Add(textSearchField);
                        }

                        entityCacheItem.TextSearchLanguages.Add(textSearchCacheItem);
                    }
                }

                _metaCache[ckTypeInfo.CkId] = entityCacheItem;
            }

            foreach (var entityCacheItem in _metaCache.Values)
            {
                BuildInheritanceGraph(ckTypeInfosDictionary[entityCacheItem.CkId], entityCacheItem);
                BuildAttributes(entityCacheItem);
            }

            foreach (var entityCacheItem in _metaCache.Values)
            {
                var ckTypeInfo = ckTypeInfosDictionary[entityCacheItem.CkId];
                BuildAssociationGraph(ckTypeInfo.Associations.Out, entityCacheItem.OutboundAssociations, entityCacheItem.CkId,
                                      GraphDirections.Outbound);
                BuildAssociationGraph(ckTypeInfo.Associations.In, entityCacheItem.InboundAssociations, entityCacheItem.CkId,
                                      GraphDirections.Inbound);
            }

            await session.CommitTransactionAsync();

            _isInitialized = true;
            Logger.Debug($"Initializing MetaCache done");
        }