internal static void Generate(TextWriter writer, string baseNamespace, Database configuration)
 {
     // NOTE SJR: Nothing is using this but they should be.
     writer.CodeBlock(
         $"namespace {baseNamespace} {{",
         () => writer.CodeBlock(
             $"public static class {className} {{",
             () => writer.WriteLine($@"public const int {commandTimeoutSecondsPropertyName} = {configuration.CommandTimeoutSecondsTyped?.ToString() ?? "null"};")));
 }
        private static void writeGetRowMatchingPkMethod(
            DBConnection cn, TextWriter writer, IDatabase database, Table table, TableColumns tableColumns, bool isSmallTable, bool tableUsesRowVersionedCaching,
            bool isRevisionHistoryTable, int?commandTimeoutSeconds)
        {
            var pkIsId       = tableColumns.KeyColumns.Count() == 1 && tableColumns.KeyColumns.Single().Name.ToLower().EndsWith("id");
            var methodName   = pkIsId ? "GetRowMatchingId" : "GetRowMatchingPk";
            var pkParameters = pkIsId
                                                   ? tableColumns.KeyColumns.Single().DataTypeName + " id"
                                                   : tableColumns.KeyColumns.Select(i => $"{i.DataTypeName} {i.CamelCasedName}").GetCommaDelimitedList();

            const string returnNullIfNoMatch = nameof(returnNullIfNoMatch);
            const string id = nameof(id);

            writer.CodeBlock(
                $"public static Row {methodName}( {pkParameters}, bool {returnNullIfNoMatch} = false ) {{",
                () => {
                if (isSmallTable)
                {
                    writer.WriteLine("var cache = Cache.Current;");
                    var commandConditionsExpression = isRevisionHistoryTable ? "new [] {getLatestRevisionsCondition()}" : "new InlineDbCommandCondition[ 0 ]";
                    writer.WriteLine("cache.Queries.GetResultSet( " + commandConditionsExpression + ", commandConditions => {");
                    writeResultSetCreatorBody(
                        cn,
                        writer,
                        database,
                        table,
                        tableColumns,
                        tableUsesRowVersionedCaching,
                        isRevisionHistoryTable,
                        "true",
                        commandTimeoutSeconds);
                    writer.WriteLine("} );");

                    var rowsByPkExpression       = $"cache.{( isRevisionHistoryTable ? "LatestRevision" : "" )}RowsByPk";
                    var pkTupleCreationArguments = pkIsId ? id : StringTools.ConcatenateWithDelimiter(", ", tableColumns.KeyColumns.Select(i => i.CamelCasedName));
                    writer.WriteLine($"if( !{returnNullIfNoMatch} )");
                    writer.WriteLine($"return {rowsByPkExpression}[ {TypeNames.Tuple}.Create( {pkTupleCreationArguments} ) ];");
                    writer.WriteLine("Row row;");
                    writer.WriteLine($"return {rowsByPkExpression}.TryGetValue( {TypeNames.Tuple}.Create( {pkTupleCreationArguments} ), out row ) ? row : null;");
                }
                else
                {
                    var condition = pkIsId
                                                                        ? $"new {table.GetEqualityConditionClassReference( cn, tableColumns.KeyColumns.Single() )}( {id} )"
                                                                        : (from keyColumn in tableColumns.KeyColumns
                                                                           let className = table.GetEqualityConditionClassReference(cn, keyColumn)
                                                                                           select $"new {className}( {keyColumn.CamelCasedName} )").GetCommaDelimitedList();
                    writer.WriteLine($"return GetRows( {condition} ).PrimaryKeySingle({returnNullIfNoMatch});");
                }
            });
        }
        private static void writeResultSetCreatorBody(
            DBConnection cn, TextWriter writer, IDatabase database, Table table, TableColumns tableColumns, bool tableUsesRowVersionedCaching, bool excludesPreviousRevisions,
            string cacheQueryInDbExpression, int?commandTimeoutSeconds)
        {
            if (tableUsesRowVersionedCaching)
            {
                writer.WriteLine("var results = new List<Row>();");
                writer.WriteLine(DataAccessStatics.DataAccessStateCurrentDatabaseConnectionExpression + ".ExecuteInTransaction( () => {");

                // Query for the cache keys of the results.
                writer.WriteLine(
                    "var keyCommand = {0};".FormatWith(
                        getInlineSelectExpression(
                            table,
                            tableColumns,
                            "{0}, \"{1}\"".FormatWith(
                                StringTools.ConcatenateWithDelimiter(", ", tableColumns.KeyColumns.Select(i => "\"{0}\"".FormatWith(i.Name)).ToArray()),
                                cn.DatabaseInfo is OracleInfo ? "ORA_ROWSCN" : tableColumns.RowVersionColumn.Name),
                            cacheQueryInDbExpression,
                            commandTimeoutSeconds)));
                writer.WriteLine(getCommandConditionAddingStatement("keyCommand"));
                writer.WriteLine($"var keys = new List<{TypeNames.Tuple}<{getPkAndVersionTupleTypeArguments( cn, tableColumns )}>>();");
                var concatenateWithDelimiter = StringTools.ConcatenateWithDelimiter(
                    ", ",
                    tableColumns.KeyColumns.Select((c, i) => c.GetDataReaderValueExpression("r", ordinalOverride: i)));
                var o = cn.DatabaseInfo is OracleInfo
                                                ? "({0})r.GetValue( {1} )".FormatWith(oracleRowVersionDataType, tableColumns.KeyColumns.Count())
                                                : tableColumns.RowVersionColumn.GetDataReaderValueExpression("r", ordinalOverride: tableColumns.KeyColumns.Count());
                writer.WriteLine(
                    "keyCommand.Execute( " + DataAccessStatics.DataAccessStateCurrentDatabaseConnectionExpression + ", r => { while( r.Read() ) keys.Add( " +
                    $"{TypeNames.Tuple}.Create( {concatenateWithDelimiter}, {o} )" + " ); } );");

                writer.WriteLine("var rowsByPkAndVersion = getRowsByPkAndVersion();");
                writer.WriteLine("var cachedKeyCount = keys.Where( i => rowsByPkAndVersion.ContainsKey( i ) ).Count();");

                // If all but a few results are cached, execute a single-row query for each missing result.
                writer.CodeBlock(
                    "if( cachedKeyCount >= keys.Count() - 1 || cachedKeyCount >= keys.Count() * .99 ) {",
                    () => {
                    writer.WriteLine("foreach( var key in keys ) {");
                    writer.WriteLine("results.Add( new Row( rowsByPkAndVersion.GetOrAdd( key, () => {");
                    writer.WriteLine("var singleRowCommand = {0};".FormatWith(getInlineSelectExpression(table, tableColumns, "\"*\"", "false", commandTimeoutSeconds)));
                    foreach (var i in tableColumns.KeyColumns.Select((c, i) => new { column = c, index = i }))
                    {
                        writer.WriteLine(
                            $"singleRowCommand.AddCondition( ( ({table.GetTableConditionInterfaceReference()})new {table.GetEqualityConditionClassReference( cn, i.column )}( key.Item{i.index + 1} ) ).CommandCondition );");
                    }

                    writer.WriteLine("var singleRowResults = new List<BasicRow>();");
                    writer.WriteLine(
                        "singleRowCommand.Execute( " + DataAccessStatics.DataAccessStateCurrentDatabaseConnectionExpression +
                        ", r => { while( r.Read() ) singleRowResults.Add( new BasicRow( r ) ); } );");
                    writer.WriteLine("return singleRowResults.Single();");
                    writer.WriteLine("} ) ) );");
                    writer.WriteLine("}");
                });
                // Otherwise, execute the full query.
                writer.CodeBlock(
                    "else {",
                    () => {
                    writer.WriteLine(
                        "var command = {0};".FormatWith(
                            getInlineSelectExpression(
                                table,
                                tableColumns,
                                cn.DatabaseInfo is OracleInfo ? "\"{0}.*\", \"ORA_ROWSCN\"".FormatWith(table) : "\"*\"",
                                cacheQueryInDbExpression,
                                commandTimeoutSeconds)));
                    writer.WriteLine(getCommandConditionAddingStatement("command"));
                    writer.WriteLine("command.Execute( " + DataAccessStatics.DataAccessStateCurrentDatabaseConnectionExpression + ", r => {");
                    writer.WriteLine(
                        "while( r.Read() ) results.Add( new Row( rowsByPkAndVersion.GetOrAdd( System.Tuple.Create( {0}, {1} ), () => new BasicRow( r ) ) ) );".FormatWith(
                            StringTools.ConcatenateWithDelimiter(", ", tableColumns.KeyColumns.Select(i => i.GetDataReaderValueExpression("r")).ToArray()),
                            cn.DatabaseInfo is OracleInfo
                                                                        ? "({0})r.GetValue( {1} )".FormatWith(oracleRowVersionDataType, tableColumns.AllColumns.Count())
                                                                        : tableColumns.RowVersionColumn.GetDataReaderValueExpression("r")));
                    writer.WriteLine("} );");
                });

                writer.WriteLine("} );");
            }
            else
            {
                writer.WriteLine("var command = {0};".FormatWith(getInlineSelectExpression(table, tableColumns, @"""*""", cacheQueryInDbExpression, commandTimeoutSeconds)));
                writer.WriteLine(getCommandConditionAddingStatement("command"));
                writer.WriteLine("var results = new List<Row>();");
                writer.WriteLine(
                    "command.Execute( " + DataAccessStatics.DataAccessStateCurrentDatabaseConnectionExpression +
                    ", r => { while( r.Read() ) results.Add( new Row( new BasicRow( r ) ) ); } );");
            }

            // Add all results to RowsByPk.
            writer.WriteLine("foreach( var i in results ) {");
            var pkTupleCreationArgs = tableColumns.KeyColumns.Select(i => "i." + Utility.GetCSharpIdentifier(i.PascalCasedNameExceptForOracle));
            var pkTuple             = "System.Tuple.Create( " + StringTools.ConcatenateWithDelimiter(", ", pkTupleCreationArgs.ToArray()) + " )";

            writer.WriteLine($"cache.RowsByPk[ {pkTuple} ] = i;");
            if (excludesPreviousRevisions)
            {
                writer.WriteLine($"cache.LatestRevisionRowsByPk[ {pkTuple} ] = i;");
            }
            writer.WriteLine("}");

            writer.WriteLine("return results;");
        }