private void AddMethodForAddOrUpdateEntity([NotNull] IDynamicallyGeneratedClass dynamicallyGeneratedClass,
                                               [NotNull] RepositoryMethodMetadata <RepositoryMethodMetadataForAddOrUpdateAttribute> repositoryMethodMetadataForAddOrUpdate,
                                               [NotNull] string entityIdToEntityMapMemberName)
    {
        var entityParamName = "entity";

        var methodData = dynamicallyGeneratedClass.StartMethod(repositoryMethodMetadataForAddOrUpdate.MethodInfo.Name,
                                                               _databaseEntityType,
                                                               new []
        {
            new MethodParameterInfo(_databaseEntityType, entityParamName, MethodParameterType.Normal)
        }, AccessLevel.Public, false, false);

        methodData.AddCodeLine("{");
        methodData.AddCodeLine($"var entityId={entityParamName}.{_keyColumnMetadata.PropertyInfo.Name};");
        methodData.AddCodeLine($"if (entityId != null && {entityIdToEntityMapMemberName}.ContainsKey(entityId.Value))");
        methodData.AddCodeLine($"throw new {typeof(Exception).FullName}($\"Entity with {_keyColumnMetadata.PropertyInfo.Name}={{entityId}} was already added.\");");
        methodData.AddCodeLine("entityId=OROptimizer.GlobalsCoreAmbientContext.Context.GenerateUniqueId();");
        methodData.AddCodeLine($"{entityParamName}.{_keyColumnMetadata.PropertyInfo.Name}=entityId.Value;");
        methodData.AddCodeLine($"{entityIdToEntityMapMemberName}[entityId.Value]={entityParamName};");

        AddDatabaseStatement(methodData, "Add of update column values", entityParamName);
        methodData.AddCodeLine($"return {entityParamName};");
        methodData.AddCodeLine("}");
    }
    private void GenerateCSharpCode([NotNull] IDynamicallyGeneratedClass dynamicallyGeneratedClass)
    {
        if (_repositoryInterfaceType == null || _databaseEntityType == null || _databaseEntityAttribute == null ||
            _keyColumnMetadata == null)
        {
            throw new Exception($"Some values were not initialized by method '{nameof(Validate)}'. This is an implementation error.");
        }

        dynamicallyGeneratedClass.AddUsingNamespaceStatement("System.Collections.Generic");
        dynamicallyGeneratedClass.AddUsingNamespaceStatement("System.Linq");
        dynamicallyGeneratedClass.AddUsingNamespaceStatement("OROptimizer.Diagnostics.Log");

        dynamicallyGeneratedClass.AddUsingNamespaceStatement("DynamicallyLoadedAssembly1.Interfaces");

        var entityIdToEntityMapMemberName = "_entityIdToEntityMap";

        // Test referencing an assembly specified in additionalAssemblyReferences element
        dynamicallyGeneratedClass.AddCodeLine("private ISomeSettings _someSettings = new DynamicallyLoadedAssembly1.Implementations.SomeSettings_Impl1();");

        dynamicallyGeneratedClass.AddCodeLine("private SharedServices.Interfaces.IDbConnection _dbConnection;");

        dynamicallyGeneratedClass.AddCodeLine($"private Dictionary<long, {_databaseEntityType.FullName}> {entityIdToEntityMapMemberName} = new Dictionary<long, {_databaseEntityType.FullName}>();");

        var constructorInfo = dynamicallyGeneratedClass.StartConstructor(new IParameterInfo[]
        {
            // Demonstrate dependency injection in custom autogenerated service.
            new OROptimizer.DynamicCode.ParameterInfo(typeof(SharedServices.Interfaces.IDbConnection), "dbConnection")
        }, AccessLevel.Public, false);

        constructorInfo.AddCodeLine("{");
        constructorInfo.AddCodeLine("if (!_someSettings.Switch) throw new System.Exception(\"The value of _someSettings.Switch should be true.\");");
        constructorInfo.AddCodeLine("_dbConnection = dbConnection;");
        constructorInfo.AddCodeLine("}");

        foreach (var repositoryMethodMetadataForAdd in _repositoryMethodMetadataForAdd)
        {
            AddMethodForAddEntity(dynamicallyGeneratedClass, repositoryMethodMetadataForAdd, entityIdToEntityMapMemberName);
        }

        foreach (var repositoryMethodMetadataForAddOrUpdate in _repositoryMethodMetadataForAddOrUpdate)
        {
            AddMethodForAddOrUpdateEntity(dynamicallyGeneratedClass, repositoryMethodMetadataForAddOrUpdate, entityIdToEntityMapMemberName);
        }

        foreach (var repositoryMethodMetadataForDelete in _repositoryMethodMetadataForDelete)
        {
            AddMethodForDeleteEntity(dynamicallyGeneratedClass, repositoryMethodMetadataForDelete, entityIdToEntityMapMemberName);
        }

        foreach (var repositoryMethodMetadataForSelectAll in _repositoryMethodMetadataForSelectAll)
        {
            AddMethodForSelectAll(dynamicallyGeneratedClass, repositoryMethodMetadataForSelectAll, entityIdToEntityMapMemberName);
        }

        foreach (var repositoryMethodMetadataForSelectSingle in _repositoryMethodMetadataForSelectSingle)
        {
            AddMethodForSelectSingle(dynamicallyGeneratedClass, repositoryMethodMetadataForSelectSingle, entityIdToEntityMapMemberName);
        }
    }
    private void AddMethodForSelectAll([NotNull] IDynamicallyGeneratedClass dynamicallyGeneratedClass,
                                       [NotNull] RepositoryMethodMetadata <RepositoryMethodMetadataForSelectAttribute> repositoryMethodMetadataForSelectAll,
                                       [NotNull] string entityIdToEntityMapMemberName)
    {
        var methodData = dynamicallyGeneratedClass.StartMethod(repositoryMethodMetadataForSelectAll.MethodInfo.Name,
                                                               repositoryMethodMetadataForSelectAll.MethodInfo.ReturnType,
                                                               new MethodParameterInfo[]
        {
        }, AccessLevel.Public, false, false);

        methodData.AddCodeLine("{");

        methodData.AddCodeLine($"return {entityIdToEntityMapMemberName}.Values.ToList();");
        methodData.AddCodeLine("}");
    }
    private void AddMethodForSelectSingle([NotNull] IDynamicallyGeneratedClass dynamicallyGeneratedClass,
                                          [NotNull] RepositoryMethodMetadata <RepositoryMethodMetadataForSelectAttribute> repositoryMethodMetadataForSelectSingle,
                                          [NotNull] string entityIdToEntityMapMemberName)
    {
        var entityIdParamName = "entityId";
        var methodData        = dynamicallyGeneratedClass.StartMethod(repositoryMethodMetadataForSelectSingle.MethodInfo.Name,
                                                                      repositoryMethodMetadataForSelectSingle.MethodInfo.ReturnType,
                                                                      new MethodParameterInfo[]
        {
            new MethodParameterInfo(typeof(long), entityIdParamName, MethodParameterType.Normal)
        }, AccessLevel.Public, false, false);

        methodData.AddCodeLine("{");
        methodData.AddCodeLine($"return {entityIdToEntityMapMemberName}.TryGetValue({entityIdParamName}, out var entity) ? entity : null;");
        methodData.AddCodeLine("}");
    }
    private void AddMethodForDeleteEntity([NotNull] IDynamicallyGeneratedClass dynamicallyGeneratedClass,
                                          [NotNull] RepositoryMethodMetadata <RepositoryMethodMetadataForDeleteAttribute> repositoryMethodMetadataForDelete,
                                          [NotNull] string entityIdToEntityMapMemberName)
    {
        var entityParamName = "entity";

        var methodData = dynamicallyGeneratedClass.StartMethod(repositoryMethodMetadataForDelete.MethodInfo.Name,
                                                               repositoryMethodMetadataForDelete.MethodInfo.ReturnType,
                                                               new []
        {
            new MethodParameterInfo(_databaseEntityType, entityParamName, MethodParameterType.Normal)
        }, AccessLevel.Public, false, false);

        methodData.AddCodeLine("{");
        methodData.AddCodeLine($"var entityId={entityParamName}.{_keyColumnMetadata.PropertyInfo.Name};");
        methodData.AddCodeLine("if (entityId == null) return;");
        methodData.AddCodeLine($"{entityIdToEntityMapMemberName}.Remove(entityId.Value);");

        methodData.AddCode($"LogHelper.Context.Log.Info(\"Delete row with key column '{_keyColumnMetadata.ColumnName}'=\"+entityId);");
        methodData.AddCodeLine("}");
    }