<commit_before>using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using Fasterflect;
using VirtualObjects.Exceptions;
using VirtualObjects.CodeGenerators;

namespace VirtualObjects.Config
{
    /// <summary>
    /// Maps a type into an IEntityInfo. Caches out the results.
    /// </summary>
    class Mapper : IMapper
    {
        private readonly IOperationsProvider _operationsProvider;
        private readonly IEntityInfoCodeGeneratorFactory _codeGeneratorFactory;
        private readonly ITranslationConfiguration _configuration;
        private readonly IEntityBag _entityBag;

        public Mapper(IEntityBag entityBag, ITranslationConfiguration configuration, IOperationsProvider operationsProvider, IEntityInfoCodeGeneratorFactory codeGeneratorFactory)
        {
            _configuration = configuration;
            _codeGeneratorFactory = codeGeneratorFactory;
            _operationsProvider = operationsProvider;
            _entityBag = entityBag;
        }

        #region IMapper Members

        public IEntityInfo Map(Type entityType)
        {
            if ( entityType.IsFrameworkType() || entityType.IsDynamic() )
            {
                return null;
            }

            if ( entityType.IsProxy() )
            {
                return Map(entityType.BaseType);
            }

            try
            {
                return MapType(entityType);
            }
            catch ( Exception ex )
            {
                throw new MappingException(Errors.UnableToMapEntity, entityType, ex);
            }
        }

        private void MapRelatedEntities(IEntityInfo entityInfo)
        {
            foreach ( var property in entityInfo.EntityType.GetProperties().Where(e => e.IsVirtual() && e.PropertyType.IsCollection()) )
            {
                var entityType = property.PropertyType.GetGenericArguments().First();
                Map(entityType);
            }
        }

        private IEntityInfo MapType(Type entityType)
        {
            IEntityInfo entityInfo;

            if ( _entityBag.TryGetValue(entityType, out entityInfo) )
            {
                return entityInfo;
            }

            _entityBag[entityType] = entityInfo = new EntityInfo
            {
                EntityName = GetName(entityType),
                EntityType = entityType
            };

            entityInfo.Columns = MapColumns(entityInfo).ToList();
            entityInfo.KeyColumns = entityInfo.Columns.Where(e => e.IsKey).ToList();

            int i = 0;
            foreach ( var column in entityInfo.Columns )
            {
                column.Index = i++;
                column.ForeignKey = GetForeignKey(column.Property);
            }

            entityInfo.Columns = WrapColumns(entityInfo.Columns).ToList();
            entityInfo.KeyColumns = entityInfo.Columns.Where(e => e.IsKey).ToList();

#if DEBUG
            entityInfo.Columns.ForEach(e =>
            {
                if ( e.ForeignKey == null && !e.Property.PropertyType.IsFrameworkType() )
                {
                    throw new ConfigException("The column [{ColumnName}] returns a complex type but is not associated with another key.", e);
                }

                if ( e.ForeignKey != null && !(e is EntityBoundColumnInfo) )
                {
                    throw new ConfigException("The column [{ColumnName}] returns a complex type but is not associated with another key.", e);
                }
            });
#endif
            //
            // Calculation of the entity Key.
            //
            entityInfo.KeyHashCode = obj => entityInfo.KeyColumns
                .Aggregate(new StringBuffer(), (current, key) => current + key.GetFieldFinalValue(obj).ToString())
                .GetHashCode();

            entityInfo.Identity = entityInfo.KeyColumns.FirstOrDefault(e => e.IsIdentity);
            entityInfo.VersionControl = entityInfo.Columns.FirstOrDefault(e => e.IsVersionControl);

            entityInfo.ForeignKeys = entityInfo.Columns.Where(e => e.ForeignKey != null).ToList();

            foreach ( var column in entityInfo.Columns )
            {
                column.ForeignKeyLinks = GetForeignKeyLinks(column, entityInfo).ToList();
            }

            MapRelatedEntities(entityInfo);

            entityInfo.Operations = _operationsProvider.CreateOperations(entityInfo);
            var codeGenerator = _codeGeneratorFactory.Make(entityInfo);

            codeGenerator.GenerateCode();

            entityInfo.MapEntity = codeGenerator.GetEntityMapper();
            entityInfo.EntityFactory = codeGenerator.GetEntityProvider();
            entityInfo.EntityProxyFactory = codeGenerator.GetEntityProxyProvider();
            entityInfo.EntityCast = codeGenerator.GetEntityCast();

            return entityInfo;
        }
<commit_msg>fix: remove columns that were used just for lazy load<commit_after>using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using Fasterflect;
using VirtualObjects.Exceptions;
using VirtualObjects.CodeGenerators;

namespace VirtualObjects.Config
{
    /// <summary>
    /// Maps a type into an IEntityInfo. Caches out the results.
    /// </summary>
    class Mapper : IMapper
    {
        private readonly IOperationsProvider _operationsProvider;
        private readonly IEntityInfoCodeGeneratorFactory _codeGeneratorFactory;
        private readonly ITranslationConfiguration _configuration;
        private readonly IEntityBag _entityBag;

        public Mapper(IEntityBag entityBag, ITranslationConfiguration configuration, IOperationsProvider operationsProvider, IEntityInfoCodeGeneratorFactory codeGeneratorFactory)
        {
            _configuration = configuration;
            _codeGeneratorFactory = codeGeneratorFactory;
            _operationsProvider = operationsProvider;
            _entityBag = entityBag;
        }

        #region IMapper Members

        public IEntityInfo Map(Type entityType)
        {
            if ( entityType.IsFrameworkType() || entityType.IsDynamic() )
            {
                return null;
            }

            if ( entityType.IsProxy() )
            {
                return Map(entityType.BaseType);
            }

            try
            {
                return MapType(entityType);
            }
            catch ( Exception ex )
            {
                throw new MappingException(Errors.UnableToMapEntity, entityType, ex);
            }
        }

        private void MapRelatedEntities(IEntityInfo entityInfo)
        {
            foreach ( var property in entityInfo.EntityType.GetProperties().Where(e => e.IsVirtual() && e.PropertyType.IsCollection()) )
            {
                var entityType = property.PropertyType.GetGenericArguments().First();
                Map(entityType);
            }
        }

        private IEntityInfo MapType(Type entityType)
        {
            IEntityInfo entityInfo;

            if ( _entityBag.TryGetValue(entityType, out entityInfo) )
            {
                return entityInfo;
            }

            _entityBag[entityType] = entityInfo = new EntityInfo
            {
                EntityName = GetName(entityType),
                EntityType = entityType
            };

            entityInfo.Columns = MapColumns(entityInfo).ToList();
            entityInfo.KeyColumns = entityInfo.Columns.Where(e => e.IsKey).ToList();

            int i = 0;
            foreach ( var column in entityInfo.Columns )
            {
                column.Index = i++;
                column.ForeignKey = GetForeignKey(column.Property);
            }

            entityInfo.Columns = WrapColumns(entityInfo.Columns).ToList();
            entityInfo.KeyColumns = entityInfo.Columns.Where(e => e.IsKey).ToList();

#if DEBUG
            entityInfo.Columns.ForEach(e =>
            {
                if ( e.ForeignKey == null && !e.Property.PropertyType.IsFrameworkType() )
                {
                    throw new ConfigException("The column [{ColumnName}] returns a complex type but is not associated with another key.", e);
                }

                if ( e.ForeignKey != null && !(e is EntityBoundColumnInfo) )
                {
                    throw new ConfigException("The column [{ColumnName}] returns a complex type but is not associated with another key.", e);
                }
            });
#endif
            //
            // Calculation of the entity Key.
            //
            entityInfo.KeyHashCode = obj => entityInfo.KeyColumns
                .Aggregate(new StringBuffer(), (current, key) => current + key.GetFieldFinalValue(obj).ToString())
                .GetHashCode();

            entityInfo.Identity = entityInfo.KeyColumns.FirstOrDefault(e => e.IsIdentity);
            entityInfo.VersionControl = entityInfo.Columns.FirstOrDefault(e => e.IsVersionControl);

            entityInfo.ForeignKeys = entityInfo.Columns.Where(e => e.ForeignKey != null).ToList();


            foreach ( var column in entityInfo.Columns )
            {
                column.ForeignKeyLinks = GetForeignKeyLinks(column, entityInfo).ToList();
            }

            foreach (var foreignKey in entityInfo.ForeignKeys
                .Where(foreignKey => foreignKey.Property.Name == foreignKey.ColumnName)
                .Where(foreignKey => foreignKey.ForeignKeyLinks != null && foreignKey.ForeignKeyLinks.Any()))
            {

                // Remove foreignKey from columns if it was used only for bind purposes.
                // This should be used when a lazy load is needed with multiple keys.
                entityInfo.Columns.Remove(foreignKey);
            }

            MapRelatedEntities(entityInfo);

            entityInfo.Operations = _operationsProvider.CreateOperations(entityInfo);
            var codeGenerator = _codeGeneratorFactory.Make(entityInfo);

            codeGenerator.GenerateCode();

            entityInfo.MapEntity = codeGenerator.GetEntityMapper();
            entityInfo.EntityFactory = codeGenerator.GetEntityProvider();
            entityInfo.EntityProxyFactory = codeGenerator.GetEntityProxyProvider();
            entityInfo.EntityCast = codeGenerator.GetEntityCast();

            return entityInfo;
        }

{'fraction_non_alphanumeric': 0.08322909650726451, 'fraction_numerical': 0.000192437217357837, 'mean_word_length': 1.9486524822695035, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7125911', 'n_tokens_mistral': 2474, 'n_tokens_neox': 2384, 'n_words': 543}