DataAccessAdapter and CatalogNameOverwriteHashtable in .NET standard

Posts   
 
    
omborddata
User
Posts: 42
Joined: 18-Apr-2012
# Posted on: 06-Feb-2020 16:22:03   

Hi,

We are setting up a new ASP.NET Core project with LLBLGEN 5.6. In our other projects where we have had LLBLGEN we create our own DataAdapter which inherit DataAccessAdapter from DatabaseSpecific.

That class basically creates a CatalogNameOverwriteHashtable and adds the original database name with the value of the current database name that we are working on. We usually have multiple databases with different names corresponding to our client names. So with this change we can access the correct database and not the original one.

However in the .NET Standard version of LLBLGEN 5.6 this feature does not seem to work. When running adapter.FetchEntityCollection it is trying to fetch data from the original database instead of the one in my connectionstring which I used in my new DataAdapter.

The adapter-class is the same for every project we setup and it is always working so there seem to be something different in .NET Standard or in LLBLGen 5.6. (We usually use LLBLGEN 5.0)

What should we do to get this working?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 06-Feb-2020 16:47:30   

How does your RuntimeConfiguration look like, could you paste that code please?

Frans Bouma | Lead developer LLBLGen Pro
omborddata
User
Posts: 42
Joined: 18-Apr-2012
# Posted on: 06-Feb-2020 18:23:19   

Hi Frans,

Sure:


 RuntimeConfiguration.ConfigureDQE<SQLServerDQEConfiguration>(
                                            c => c.SetTraceLevel(TraceLevel.Verbose)
                                                    .AddDbProviderFactory(typeof(System.Data.SqlClient.SqlClientFactory))
                                                    .SetDefaultCompatibilityLevel(SqlServerCompatibilityLevel.SqlServer2012));

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 07-Feb-2020 02:10:49   

You need to add the overwrites to the RuntimeConfiguration: e.g.

RuntimeConfiguration.ConfigureDQE<SQLServerDQEConfiguration>(
                            c=>c.AddCatalogNameOverwrite("oldCatalogName1", "newCatalogName1")
                                .AddCatalogNameOverwrite("oldCatalogName2", "newCatalogName2"));
omborddata
User
Posts: 42
Joined: 18-Apr-2012
# Posted on: 07-Feb-2020 07:43:46   

Hi,

We need to change the connection string per request. There are multiple databases connected to the site. If we cannot use the usual catalog-replace-function, can the runtime-configuration be set per request and if so how do we do that?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 07-Feb-2020 10:59:48   

Our tests work fine, so it might be something you're doing with the hashtable. See this test for how we do it:

[Test]
public void ProcWithDotNameNameOverwritingTest()
{
    var catalogOverwrites = new CatalogNameOverwriteHashtable();
    catalogOverwrites.Add("Northwind", "Northwind2");
    using(var adapter = new DataAccessAdapter())
    {
        adapter.CatalogNameOverwrites = catalogOverwrites;
        DataTable results1 = RetrievalProcedures.Test123(adapter);
        Assert.AreEqual(93, results1.Rows.Count);
    }
}

this works fine on .net core and .net fx (we run the tests on both targets). For collection fetches, same thing, it works fine on .net core and .net fx. So I think you do something differently with the catalog name overwrites. Could you show the code which sets your catalog name overwrites?

Frans Bouma | Lead developer LLBLGen Pro
omborddata
User
Posts: 42
Joined: 18-Apr-2012
# Posted on: 07-Feb-2020 14:05:43   

We have now changed to use the code like in your post but still not fetching from the right database. (which in this case is ODInfoCenter_Dev2)


Public Function FindByEmail(email As String) As UserEntity

            ErrorManager.Info("FindByEmailAsync - email:" & email)
            If String.IsNullOrEmpty(email) Then
                Throw New ArgumentException("Null or empty argument: email")
            End If

            Dim entCol As New EntityCollection(New UserEntityFactory())

            'This is the override connection string which is set at another place but put here for this example
            mConnString = "Data Source=sql04\\dev2014;Initial Catalog=ODInfoCenter_Dev2;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
            Dim catalogOverwrites As CatalogNameOverwriteHashtable = ODInfocenterCoreDataAccessAdapter.GetCataLogNameOverwriteHashtable(mConnString)
            ErrorManager.Info("FindByEmailAsync - Conn:" & mConnString)

            Dim filterBucket As New RelationPredicateBucket
            Dim expr As IPredicateExpression = New PredicateExpression()
            expr.Add(UserFields.Email = email)
            filterBucket.PredicateExpression.Add(expr)

            Using adapter = New DatabaseSpecific.DataAccessAdapter()
                Try
                    adapter.CatalogNameOverwrites = catalogOverwrites
                    adapter.FetchEntityCollection(entCol, filterBucket)
                Catch ex As Exception
                    ErrorManager.Exception(ex)
                End Try
            End Using

            If entCol IsNot Nothing AndAlso entCol.Count > 0 Then
                Return entCol.Item(0)
            End If

            Return Nothing
        End Function

In startup.cs we set the following at last in Configure:


//LLBLGEN CONFIGURATION **********************************************************
            RuntimeConfiguration.AddConnectionString("ConnectionString.SQL Server (SqlClient)",
                                                "Data Source=sql04\\dev2014;Initial Catalog=ODInfoCenter_Dev;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False");
            // Configure the DQE
            RuntimeConfiguration.ConfigureDQE<SQLServerDQEConfiguration>(
                                          c => c.SetTraceLevel(TraceLevel.Verbose)
                                                  .AddDbProviderFactory(typeof(System.Data.SqlClient.SqlClientFactory))
                                                  .SetDefaultCompatibilityLevel(SqlServerCompatibilityLevel.SqlServer2012));

The helper method to construct the CatalogNameOverwriteHashTable:


Public Shared Function GetCataLogNameOverwriteHashtable(conn As String) As SD.LLBLGen.Pro.ORMSupportClasses.CatalogNameOverwriteHashtable
        Dim newCatalogName As SD.LLBLGen.Pro.ORMSupportClasses.CatalogNameOverwriteHashtable = New SD.LLBLGen.Pro.ORMSupportClasses.CatalogNameOverwriteHashtable()
        Dim connBuilder As New System.Data.SqlClient.SqlConnectionStringBuilder(conn)
        'newCatalogName.Add("ODInfoCenter", connBuilder.InitialCatalog)
        newCatalogName.Add("ODInfoCenter_Dev", connBuilder.InitialCatalog)

        Return newCatalogName
    End Function

omborddata
User
Posts: 42
Joined: 18-Apr-2012
# Posted on: 07-Feb-2020 14:07:08   

Here is console output:


Method Enter: CreatePagingSelectDQ
Method Enter: CreateSelectDQ
Generated Sql query: 
    Query: SELECT [ODInfoCenter_DEV].[dbo].[AspNetUsers].[AccessFailedCount], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[Email], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[EmailConfirmed], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[FirstName], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[FKCrewId] AS [FkcrewId], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[IsAdmin], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[IsRestHourAdmin], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[LastName], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[LockoutEnabled], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[LockoutEndDateUtc], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[PasswordHash], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[SecurityStamp] AS [PasswordSalt], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[PhoneNumber], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[PhoneNumberConfirmed], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[ShipLimitList], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[Status], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[TwoFactorEnabled], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[Id] AS [UserId], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[UserName], [ODInfoCenter_DEV].[dbo].[AspNetUsers].[XOICCode] AS [Xoiccode] FROM [ODInfoCenter_DEV].[dbo].[AspNetUsers] WHERE ( ( [ODInfoCenter_DEV].[dbo].[AspNetUsers].[Email] = @p1))
    Parameter: @p1 : AnsiString. Length: 256. Precision: 0. Scale: 0. Direction: Input. Value: "test2@hotmail.se".
Method Exit: CreateSelectDQ
Method Exit: CreatePagingSelectDQ: no paging.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 07-Feb-2020 14:38:37   

The query contains "ODInfoCenter_DEV" (so the meta-data does too), the overwrites contain "ODInfoCenter_Dev"

I think that's the reason it doesn't work anymore, the comparison is case sensitive. I've tested this and when I have the casing wrong in my test (northwind compared to Northwind) it indeed doesn't overwrite the catalog name.

Please change the ODInfoCenter_Dev string in ODInfoCenter_DEV to fix the problem. (Or use '*' as source name to overwrite any catalog name to the new name specified. If you use just 1 catalog name that could be perhaps a way to keep it working if the dev database name changes as well).

Frans Bouma | Lead developer LLBLGen Pro
omborddata
User
Posts: 42
Joined: 18-Apr-2012
# Posted on: 07-Feb-2020 14:44:18   

Haha, I was going crazy here. Because I just tried to do a sample project for you to test and in that project it worked.

I remember now that it is case sensitive when you mentioned it and when I changed the Catalog-helper it sure works. :-)

Thanks for the help Frans! I would have surely put my entire weekend into trying to fix this. :-D

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 07-Feb-2020 16:54:12   

Sorry for this inconvenience and I'm glad it didn't ruin your weekend! simple_smile I noticed we don't explicitly mention it is case sensitive so we'll add a note to the docs to clarify this so others won't waste time over this as well simple_smile

Frans Bouma | Lead developer LLBLGen Pro