Migration LLBLGen Pro Runtime from 5.7 to 5.10 - No connection string specified

Posts   
 
    
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 07-Jan-2024 09:02:35   

Hello After Migrating our LLBLGen Pro Runtime from 5.7 to 5.10 I have problem receiving connection string

ErrorMessage : No connection string specified. Please specify a connection string in the app/web.config file or through the RuntimeConfiguration system.
StackTrace:

   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.CreateNewPhysicalConnection(String connectionString)

   at SD.LLBLGen.Pro.ORMSupportClasses.AdapterSpecific.TransactionAdapter.CreateConnection(String connectionString)

   at SD.LLBLGen.Pro.ORMSupportClasses.TransactionBase.AssureConnectionIsPresent()

   at SD.LLBLGen.Pro.ORMSupportClasses.Adapter.QueryCreationManager.CreateSelectDQ(QueryParameters parameters)

   at Ness.ProvidentFunds.Common.DataAccess.Extensions.Services.NessQueryCreationManager.CreateSelectDQ(QueryParameters parameters) in c:\Builds\6\Gaya\GAYA_BUILD.4.8_AUTO\Sources\DataAccess\All\Ness.ProvidentFunds.Common.DataAccess.Extensions\NessDataAccessAdapter\Services\NessQueryCreationManager.cs:line 125

   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollectionInternal(QueryParameters parameters)

   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(QueryParameters parameters)

   at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.<>c__DisplayClass10_0.<FetchEntityCollection>b__0()

   at Ness.ProvidentFunds.Common.DataAccess.Extensions.NessDataAccessAdapter.FetchEntityCollection(QueryParameters parameters) in c:\Builds\6\Gaya\GAYA_BUILD.4.8_AUTO\Sources\DataAccess\All\Ness.ProvidentFunds.Common.DataAccess.Extensions\NessDataAccessAdapter\NessDataAccessAdapter.cs:line 153

   at Ness.ProvidentFunds.Common.DataAccess.Extensions.DataAccessAdapterExceptionsDecorator.FetchEntityCollection(IEntityCollection2 collectionToFill, IRelationPredicateBucket filterBucket, Int32 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPrefetchPath2 prefetchPath, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize) in c:\Builds\6\Gaya\GAYA_BUILD.4.8_AUTO\Sources\DataAccess\All\Ness.ProvidentFunds.Common.DataAccess.Extensions\NessDataAccessAdapter\DataAccessAdapterExceptionsDecorator.cs:line 531
we use a custom configuration for connection string from web.config and not the default key from appSettings (<add key="Main.ConnectionString.Oracle (ODP.NET)…")

therefor on our DataAccessAdapter I have override the ConnectionString Property

public override string ConnectionString

        {

            get

            {

              

                return m_connectionString;

            }

            set

            {

                if (m_connectionString == null)

                {

                    IConnectionStringProvider provider = new ConfigurationDalAppConfigConnStringProvider();

                    m_connectionString = provider.GetConnectionString();                

                }

                base.ConnectionString = m_connectionString;

            }

        }

On previews version all CreateSelectDQ functions been at the DataAccessAdapter and received the connection string

In new version since 5.8 refactoring the CreateSelectDQ moved to the new class QueryCreationManager which not contains the property ConnectionString

I can't override it at that deriving class and there for its probably go to default config value Main.ConnectionString.Oracle (ODP.NET).

How can I set or override to the custom connection string config value for that new class as well as done for the DataAccessAdapter?

Thank you

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 08-Jan-2024 09:28:35   

The Connection string is either read from the config file (.net framework builds) or passed in using the RuntimeConfiguration class. Your adapter that fails is that your client version (which you derive yourself from dataaccessadaptercore) or the server side one? And which .net version are you using (e.g. if you use .net 6+, you have to use the RuntimeConfiguration class)

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 08-Jan-2024 10:06:00   

I am using framework 4.8 the adapter is the server side which derive from dataaccessadaptercore and override the connection string , loading connection string success while using its fetch methods . but, the class that failed to load connection string is the new class that inherit QueryCreationManager when using the CreateSelectDQ method. somehow the ConnectionString is not passes to that class. and i cant find away to do it. here's the code :

public class NessQueryCreationManager : QueryCreationManager

    {

 

        [NessDependency]

        public ISelectDQDependencyBuilder SelectDQDependencyBuilder { get; set; }

        #region constants

 

        private const string _traceLLBLGENQueryesTitle = "LLBLGEN_Queries";

        private const string _llblgenSaveErrorsTitle = "LLBLGEN_Save_Errors";

        private const string _resultCountTraceTitle = "LLBLGEN_ResultCount";

 

        #endregion

        #region ctor

        public NessQueryCreationManager(DataAccessAdapterCore containingAdapter, IPersistenceInfoProvider persistenceInfoProvider)

           : base(containingAdapter, persistenceInfoProvider)

        {

  

        }

 

        #endregion

 

        #region private members     

 

        private readonly TraceWriterHelper _traceHelper = new TraceWriterHelper();

 

        #endregion

 

        #region CreateDQ override

 

        protected override IRetrievalQuery CreateSelectDQ(QueryParameters parameters)

        {

            long maxNumberOfItemsToReturn = (long)parameters.RowsToTake;

 

            IPredicateExpression filter = parameters.FilterToUseAsPredicateExpression;

 

            if (filter == null)

            {

                filter = new PredicateExpression();

            }

 

            //  ISelectDQDependencyBuilder selectDQDependencyBuilder = new SelectDQDependencyBuilder();

            ISelectDQDependencyBuilder selectDQDependencyBuilder =

               ServerFactoryBuilder.Create().Resolve<ISelectDQDependencyBuilder>();

            selectDQDependencyBuilder.AddDependencyToSelectDQObjects

          (

                 parameters.RelationsToUse,

                 filter,

                 (IEntityFields2)parameters.FieldsForQuery

 

           );

 

            this.InsertPersistenceInfoObjects(parameters.RelationsToUse);

            this.InsertPersistenceInfoObjects(filter);

 

            if (parameters.RowsToTake == 0)

            {

                parameters.RowsToTake = (int)this.GetMaxNumberOfItemsToReturn(maxNumberOfItemsToReturn);

            }
 

            IRetrievalQuery updatedQuery = base.CreateSelectDQ(parameters);
 

            updatedQuery.Command.CommandText = updatedQuery.Command.CommandText.ToUpper();

            //write to trace

            this._traceHelper.TraceQuery(updatedQuery, "CreateSelectDQ-after using entity relations. User : " + GetCurrentUser() + " , ManagingOrg : " + new IrgunMenahelKodProvider().GetCurrentIrgunMenahelKod(), _traceLLBLGENQueryesTitle);
 

            return updatedQuery;
 

        }

 

        #endregion CreateDQ override

 

        #region Private methods

        /// <summary>

        /// get max number of items to return

        /// if page size not defined ( <=0 ) , get number from

        /// </summary>

        private long GetMaxNumberOfItemsToReturn(long maxNumberOfItemsToReturn)

        {

            DataAccessConfigurationSection dalConfigurationSection =

                    ConfigurationServiceBuilder.GetConfigurationService().GetSection<DataAccessConfigurationSection>();

 

            return maxNumberOfItemsToReturn == 0 ? dalConfigurationSection.MaxNumberOfItemsToReturn : maxNumberOfItemsToReturn;

        }
 

        private String GetCurrentUser()

        {

            IEnvironmentInformationProvider environmentInformationProvider =

                ServerFactoryBuilder.Create().Resolve<IEnvironmentInformationProvider>();
 

            string currentUser = environmentInformationProvider.GetUserName(); 

            return currentUser;

        }
 

        #endregion
 

    }

the Exception occurs at thtis line : IRetrievalQuery updatedQuery = base.CreateSelectDQ(parameters);

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 08-Jan-2024 11:54:23   

You have to give more context and the full classes you're using. You quote code snippets but where they're used exactly isn't clear. As from a previous thread of yours you said you use a client side adapter and a server side adapter, so which one is it where the connection string fails? and additionally, please give the full adapter class you use that fails

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 08-Jan-2024 13:42:13   

Otis wrote:

You have to give more context and the full classes you're using. You quote code snippets but where they're used exactly isn't clear. As from a previous thread of yours you said you use a client side adapter and a server side adapter, so which one is it where the connection string fails? and additionally, please give the full adapter class you use that fails

While using FetchEntityCollection

The base.FetchEntityCollection(parameters);

Is calling inside to CreateSelectDQ, wich located now at the new class QueryCreationManager

When I set this key value in config its ok <add key="Main.ConnectionString.Oracle (ODP.NET)" value="…

Buy I want to use other config in custom manner when all the data access types using same key value

The CreateSelectDQ which is now in new class NessQueryCreationManager is failed retrieve connection string since it is no longer apart of the DataAccessAdapter

How can I override its connection string to use my custom one.

This is our NessDataAccessAdapter containing the override of ConnectionString Property and the override of CreateQueryCreationManager.

public class NessDataAccessAdapter : DataAccessAdapter
    {      
        static string m_connectionString;
        #region constants
   
        private const string _traceLLBLGENQueryesTitle = "LLBLGEN_Queries";
        private const string _llblgenSaveErrorsTitle = "LLBLGEN_Save_Errors";
        private const string _resultCountTraceTitle = "LLBLGEN_ResultCount";
       
        #endregion
        #region ctor
        public NessDataAccessAdapter()
            : base()
        {         
        }
      
        #endregion
 
        #region Dependency Properties
 
        public override string ConnectionString
        {
            get
            {
              
                return m_connectionString;
            }
            set
            {
                if (m_connectionString == null)
                {
                    IConnectionStringProvider provider = new ConfigurationDalAppConfigConnStringProvider();
                    m_connectionString = provider.GetConnectionString();                
                }
                base.ConnectionString = m_connectionString;
            }
        }
 
        [NessDependency]
        public IGetEntitySectionConfigurationValuesProvider GetEntitySectionConfigurationValuesProvider { get; set; }
 
        [NessDependency]
        public IUpdateEntityFieldsService UpdateEntityFieldsService { get; set; }
      
       // [NessDependency]
        //public INessQueryCreationManager NessQueryCreationManager { get; set; }
 
        [NessDependency]
        public ISelectDQDependencyBuilder SelectDQDependencyBuilder { get; set; }
 
        #endregion
 
        #region private members     
 
        private readonly TraceWriterHelper _traceHelper = new TraceWriterHelper();
 
        #endregion
 
 
        #region public override IDataAccessAdapter fetch methods
        protected override QueryCreationManager CreateQueryCreationManager(IPersistenceInfoProvider persistenceInfoProvider)
        {
            //NessQueryCreationManager nessQueryCreationManager = ServerFactoryBuilder.Create().Resolve<NessQueryCreationManager>();
            return new NessQueryCreationManager(this,persistenceInfoProvider);
 
            //return  ServerFactoryBuilder.Create().Resolve<NessQueryCreationManager>();
 
        }
        public override void FetchEntityCollection(QueryParameters parameters)
        {
 
            base.FetchEntityCollection(parameters);
            this._traceHelper.TraceCount(parameters.CollectionToFetch.Count.ToString(), "result count", "FetchEntityCollection", _resultCountTraceTitle);
        }
       
   
        #endregion
 
        #region public override IDataAccessAdapter Save methods
 
        /// <summary>
        /// overrides <see cref="Ness.ProvidentFunds.Server.DataAccess.DatabaseSpecific.DataAccessAdapter.SaveEntity"/>
        /// </summary>
        public override bool SaveEntity(IEntity2 entityToSave, bool refetchAfterSave, IPredicateExpression updateRestriction, bool recurse)
        {
            const string methodName = "SaveEntity";
            const string messageDescription = "SaveEntityInfo : ";
 
            Guard.ThrowIfNull(entityToSave, "entityToSave");
            try
            {
                // update entity fields before save
                this.UpdateEntityFieldsService.UpdateEntityFields(entityToSave);
 
                bool result = base.SaveEntity(entityToSave, refetchAfterSave, updateRestriction, recurse);
 
                this.HandleSaveEntityResult(entityToSave, refetchAfterSave, recurse, methodName, messageDescription, result);
 
                return result;
            }
            catch (Exception ex)
            {
                this._traceHelper.TraceErrors(ex.ToString(), messageDescription, methodName, _llblgenSaveErrorsTitle);
 
                throw new SaveEntityException(ex);
            }
        }

        /// <summary>
        /// overrides <see cref="Ness.ProvidentFunds.Server.DataAccess.DatabaseSpecific.DataAccessAdapter.SaveEntityCollection"/>
        /// </summary>
        public override int SaveEntityCollection(IEntityCollection2 collectionToSave, bool refetchSavedEntitiesAfterSave, bool recurse)
        {
            Guard.ThrowIfNull(collectionToSave, "collectionToSave");
 
            const string methodName = "SaveEntityCollection";
            const string messageDescription = " SaveEntityCollection :";
 
            try
            {               
                // update entity fields collection before save
                this.UpdateEntityFieldsService.UpdateEntityFieldsCollection(collectionToSave);
 
                int result = base.SaveEntityCollection(collectionToSave, refetchSavedEntitiesAfterSave, recurse);
               
                this.HandleSaveEntityCollectionResult(collectionToSave, refetchSavedEntitiesAfterSave, recurse, methodName, messageDescription, result);
               
                return result;
            }
            catch (Exception ex)
            {
                _traceHelper.TraceErrors(ex.ToString(), messageDescription, methodName, _llblgenSaveErrorsTitle);
 
                throw new SaveEntityException(ex);
            }
        }
 
        #endregion
     
        #region CreateDQ override
        /* Methods Moved to NessQueryCreationManager */
        #endregion CreateDQ override
 
        #region Private methods
        /// <summary>
        /// get max number of items to return
        /// if page size not defined ( <=0 ) , get number from
        /// </summary>
        private long GetMaxNumberOfItemsToReturn(long maxNumberOfItemsToReturn)
        {
            DataAccessConfigurationSection dalConfigurationSection =
                    ConfigurationServiceBuilder.GetConfigurationService().GetSection<DataAccessConfigurationSection>();
 
            return maxNumberOfItemsToReturn == 0 ? dalConfigurationSection.MaxNumberOfItemsToReturn : maxNumberOfItemsToReturn;
        }

        private String GetCurrentUser()
        {
            IEnvironmentInformationProvider environmentInformationProvider =
                ServerFactoryBuilder.Create().Resolve<IEnvironmentInformationProvider>();
 
            string currentUser = environmentInformationProvider.GetUserName();
 
            return currentUser;
        }
        #endregion
 
      
        #region handle Data Access Adapter override methods results
        /// <summary>
        /// display save errors details
        /// </summary>
        private void HandleSaveEntityResult(IEntity2 entityToSave, bool refetchAfterSave, bool recurse, string methodName, string messageDescription, bool result)
        {
            if (result)
            {
                return;
            }

          Type entityType =
                    entityToSave == null ? null : entityToSave.GetType();
          string entityTypeName =
                 entityType == null ?
                     "null" : entityType.Name;
           string message =
                    string.Format
                    (
                        "SaveEntity return false for entity <{0}> , refetchAfterSave = <{1}>,recurse = <{2}>",
                         entityTypeName,
                         refetchAfterSave.ToString(),
                         recurse.ToString()
                    );
           this._traceHelper.TraceErrors(message, messageDescription, methodName, _llblgenSaveErrorsTitle);
        }
        /// <summary>
        /// handle save entity collection result
        /// </summary>
        private void HandleSaveEntityCollectionResult(IEntityCollection2 collectionToSave, bool refetchSavedEntitiesAfterSave, bool recurse, string methodName, string messageDescription, int result)
        {
            if (result >= 0) return;
            Type type =
                    collectionToSave.GetType();      
            string typeName =
                    type == null ?
                    "null" : type.Name;
             string message =                 string.Format
                 (
                    "SaveEntityCollection return false for entity <{0}> , refetchAfterSave = <{1}>,recurse = <{2}>",
                     typeName,
                     refetchSavedEntitiesAfterSave.ToString(),
                     recurse.ToString()
                  ); 
            this._traceHelper.TraceErrors(message, messageDescription, methodName, _llblgenSaveErrorsTitle);           
        }
        #endregion
    }
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 08-Jan-2024 15:09:25   

The connection string is read in the generated method ReadConnectionStringFromConfig in DataAccessAdapter. This method is called from the default ctor, so if you do:

var a = new NessDataAccessAdapter();

it will end up in that method. However if you generate code for netstandard or .net 6+ the ReadConnectionStringFromConfig method will have a call to RuntimeConfiguration. You can easily check this in the debugger. Please create a simple line of code like the one above and set a breakpoint at the DataAccessAdapter.ReadConnectionStringFromConfig method in the generated DataAccessAdapter class. This should then take you through the read action for the connection string.

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 08-Jan-2024 20:55:02   

Otis wrote:

The connection string is read in the generated method ReadConnectionStringFromConfig in DataAccessAdapter. This method is called from the default ctor, so if you do:

var a = new NessDataAccessAdapter();

it will end up in that method. However if you generate code for netstandard or .net 6+ the ReadConnectionStringFromConfig method will have a call to RuntimeConfiguration. You can easily check this in the debugger. Please create a simple line of code like the one above and set a breakpoint at the DataAccessAdapter.ReadConnectionStringFromConfig method in the generated DataAccessAdapter class. This should then take you through the read action for the connection string.

Hi Otis I am using Target Platform .NET 4.8 the Adapter using the base ctor in generated DataAccesAdapter with DataAccessAdapter.ReadConnectionStringFromConfig, that read the connection string from config file - key value is declared in that generated adapter as public static string ConnectionStringKeyName= "Main.ConnectionString.Oracle (ODP.NET)"; and in debug it is going through the read action for the connection string in DataAccessAdapter ctor its right and working when using this default key . but, we don't want to use that key and at some point we removed it from config and used overriding the property ConnectionString in our adapter which replaced the default one. but now its seems like its not using that property . is there any change have been made in the last versions related the ConnectionString? that its not using the override property of ConnectionString? or any way to override the DataAccessAdapter.ReadConnectionStringFromConfig

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 09-Jan-2024 11:37:03   

Ah right. The generated adapter has a constructor public DataAccessAdapter(string connectionString) : this(connectionString, false, null, null) { } which ends up in InitClassPhase2 where it passes the connection string to the constructor of the contained TransactionAdapter

The connectionstring property of the base class sets the connectionstring on the contained TransactionAdapter instance, but it's not used if there's already an open connection. I think you don't use a TransactionAdapter on the client (as that was the reason the dispose failed with a null reference exception IIRC) so it's not used.

I'm honestly confused what the real problem is however, as you use a customized class on the client but also need the full adapter code there?

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 09-Jan-2024 12:46:15   

Otis wrote:

Ah right. The generated adapter has a constructor public DataAccessAdapter(string connectionString) : this(connectionString, false, null, null) { } which ends up in InitClassPhase2 where it passes the connection string to the constructor of the contained TransactionAdapter

The connectionstring property of the base class sets the connectionstring on the contained TransactionAdapter instance, but it's not used if there's already an open connection. I think you don't use a TransactionAdapter on the client (as that was the reason the dispose failed with a null reference exception IIRC) so it's not used.

I'm honestly confused what the real problem is however, as you use a customized class on the client but also need the full adapter code there?

the other post with the disposed from clientAdapter is ok . This post is related to the server Adapter NessDataAccessAdapter. where the ConnectionString got overrided and QuaryManager got separated from DataAccessAdapter.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 09-Jan-2024 13:49:33   

Ok, so if you want to set the connection string on the server side, you have to pass in the connectionstring through the constructor that accepts the connection string. Did you try that?

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 09-Jan-2024 16:30:17   

Otis wrote:

Ok, so if you want to set the connection string on the server side, you have to pass in the connectionstring through the constructor that accepts the connection string. Did you try that?

OK, I did try it now , passed in the connectionString through a (new ) constructor,

Now its working simple_smile , thanks!!

I had to refracture a bit my Factory to create the Adapter with new CTOR having the paramter ConnectionString and pass it to the base one.

public NessDataAccessAdapter(string connectionString) :base(connectionString) {}

just for thoughts ,it was better to save backward compatibly, if it was still able to use the overridden property ConnectionString from DataAccessAdapter as it was in previous versions.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 10-Jan-2024 09:00:15   

guyronen wrote:

just for thoughts ,it was better to save backward compatibly, if it was still able to use the overridden property ConnectionString from DataAccessAdapter as it was in previous versions.

I see we have a design flaw indeed. While setting the connectionstring property does set the connectionstring in the transaction object, the adapter creates the transaction object at creation time so it immediately opens the connection. Setting the connectionstring afterwards has then no effect.

We'll look into changing this behavior.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 10-Jan-2024 11:18:28   

I can't reproduce it actually.

[Test]
public void DifferentConnectionStringTest()
{
    IEntity2 c = new CustomerEntity("ALFKI");
    // set the connectionstring to an invalid one on the adapter, it should throw an exception
    using(var adapter = new DataAccessAdapter())
    {
        adapter.ConnectionString = "data source=server;initial catalog=Northwind;user id=someuser;pwd=somepassword;persist security info=False;packet size=4096;Encrypt=false";
        Assert.Throws(typeof(SqlException), ()=>adapter.FetchEntity(c));
    }
}

The connection string set here in my test is wrong, it has a bad userid/password. This is immediately used in the fetch because what I initially thought was the case isn't actually: the transaction isn't opening a connection immediately. That is, if you follow the call path from the default constructor ( new DataAccessAdapter()).

So I have the feeling when you set the connection string property the connection is already open. Is that the case? Please post a code snippet that reproduces the problem

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 10-Jan-2024 15:58:30   

Hi Otis I am not initiating ConnectionString by setting into Adapter.ConnectionString Property. I have overrides the inner Adapter DataAccessAdapterCore.ConnectionString and setting it from there base.ConnectionString = m_connectionString; this propert getreturn the value like I posted earlier in my inheritor class NessDataAccessAdapter


public NessDataAccessAdapter()
            : base()
        {         
        }

private static string m_connectionString;

public override string ConnectionString
        {
            get
            {              
                return m_connectionString;
            }
            set
            {
                if (m_connectionString == null)
                {
                    IConnectionStringProvider provider = new ConfigurationDalAppConfigConnStringProvider();
                    m_connectionString = provider.GetConnectionString();                
                }
                base.ConnectionString = m_connectionString;
            }
        }

So, in llblGenRuntime version 5.7.2 your infrastructure supported it and once you create an instance of DataAccessAdapter its hit this property .. in version 5.10 it is not .. that's was my problem you can try it by create class Adapter that inherited DataAccessAdapter as I did : public class NessDataAccessAdapter : DataAccessAdapter using the empty ctor : public NessDataAccessAdapter() : base() {
} then override the property ConnectionString when create new yourDataAccessAdapter you will see in 5.7.2 , when debug it will go through the property and in version 5.10 it wont

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 10-Jan-2024 20:44:02   

I see you have created NessQueryCreationManager, inheriting from QueryCreationManager, how exactly are you using this class, and do you pass an object of NessAdapter to its CTor?

guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 11-Jan-2024 07:53:02   

Walaa wrote:

I see you have created NessQueryCreationManager, inheriting from QueryCreationManager, how exactly are you using this class, and do you pass an object of NessAdapter to its CTor?

have a look up on the NessDataAccessAdapter there is an override for CreateQueryCreationManager as requested by the migration of 5.8 change

protected override QueryCreationManager CreateQueryCreationManager(IPersistenceInfoProvider persistenceInfoProvider)
        {      
            return new NessQueryCreationManager(this,persistenceInfoProvider);
  
        }
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39617
Joined: 17-Aug-2003
# Posted on: 11-Jan-2024 10:31:47   

It's indeed an internal refactoring that causes the flow of the connectionstring no longer go through the property, we directly set it on the transaction object (the wrapper which controls it); and setting the property does the same thing. Previously (before 5.sunglasses we had all that code in the DataAccessAdapter base class so we set the property indeed, hence it worked in your case.

I don't think we should refactor it to go through the property, but it's good to know why your code failed, so if another person runs into this we know why simple_smile Please use the constructor which is meant for this situation instead.

Frans Bouma | Lead developer LLBLGen Pro
guyronen
User
Posts: 26
Joined: 02-Mar-2021
# Posted on: 11-Jan-2024 11:10:17   

OK , Thank you Otis simple_smile