Search code examples
postgresqlt4linq2db

Linq2DB unable to connect to Postgres database using T4


I am trying to connect to my Postgres database in my T4 file using the following code:

<#@ template language="C#" debug="True" hostSpecific="True" #>
<#@ output extension=".cs"#>
<#@ include file="$(LinqToDBT4PostgreSQLTemplatesDirectory)LinqToDB.PostgreSQL.Tools.ttinclude" #>
<#@ include file="$(LinqToDBT4PostgreSQLTemplatesDirectory)PluralizationService.ttinclude"      #>
<# //@ include file="$(ProjectDir)LinqToDB.Templates\LinqToDB.PostgreSQL.Tools.ttinclude" #>
<# //@ include file="$(ProjectDir)LinqToDB.Templates\PluralizationService.ttinclude"      #>
<#

LoadPostgreSQLMetadata("localhost", "5433", "local_db", "postgres", "password");

GenerateModel();

#>

When I save the file in Visual Studio 2019, I get the following error:

Compiling transformation: 'ISqlBuilder' does not contain a definition for 'BuildTableName' and no 
accessible extension method 'BuildTableName' accepting a first argument of type 'ISqlBuilder' could 
be found (are you missing a using directive or an assembly reference?)

This is my first foray into using Linq2DB in T4, normally I have used SQL Server using SQLClient, but this project is using Postgres v11 and v14.

I am sure that it is something the I have not configured.

I have followed the following:

Can't generate data context with t4 template. PostgreSQL + MySql

Not 100% sure what the versions have to do with it, but here goes:

  • Visual Studio 2019 (Version 16.11.15)
  • Linq2Db installed from NuGet. Latest
  • Linq2Db.Postgres installed from NuGet. Lastest
  • NgpSQL installed from Nuget. Latest

enter image description here

UPDATE

I now have it working, but all I am interested in is generating enums from my database, I do not need it to generate a complete db context.

Is that possible?


Solution

  • For anyone that is interested, i have found a combination of Linq2DB and Npgsql sorted out the issue.

    Using the following code:

    <#@ template language="C#" debug="True" hostSpecific="True" #>
    <#@ output extension=".generated.cs"                        #>
    <#@ assembly name="EnvDTE" #>
    <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
    <#@ include file="$(LinqToDBT4PostgreSQLTemplatesPath)LinqToDB.PostgreSQL.Tools.ttinclude" once="true" #>
    <#@ include file="$(LinqToDBT4PostgreSQLTemplatesPath)PluralizationService.ttinclude"      once="true" #>
    <#@ import namespace="Npgsql" #>
    
    using System;
    using System.CodeDom.Compiler;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
     
    namespace MyProject.Enums
    {
        /// <summary>
        /// table name auto generated enumeration
        /// </summary>
    
    <#
    
    bool boolfound = false;
    using (NpgsqlConnection conn = new NpgsqlConnection("Server=localhost; Port=5432; User Id=username; Password=*****; Database=abc123"))
    {
        conn.Open();
        NpgsqlCommand cmd = new NpgsqlCommand("SELECT * FROM public.\"Table\"", conn);
        NpgsqlDataReader dr = cmd.ExecuteReader();
        if (dr.Read())
        {
            boolfound = true;
            #>
            connection established
            <#
        }
        if (boolfound == false)
        {
            #>
            Data does not exist
            <#
        }
        dr.Close();
    }
    #>
    
    }
    

    This generates the following code:

    using System;
    using System.CodeDom.Compiler;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
     
    namespace MyProject.Enums
    {
        /// <summary>
        /// table name auto generated enumeration
        /// </summary>
    
            connection established
            
    }