First off… thanks for the help thus far. As I proceed deeper into the conversion to RO/.NET I am now having an issues with the ConnectionManager. And of course it does not help being a newb with C#.
As the DA Server starts up in the main thread, I read some settings from an INI file and load the XML daConnections file. Followed by decrypting the password in each connectionstring, then storing the unencrypted password back into the connectionstring; At this point all appears well. and I can confirm that the connectionstrings are well formed.
Then I run a simple query from my interface. But when I check e.Connection.ConnectionString while in the BeforeAcquireConnection of the respective IMPL file, it is blank. If I include a new connection managers on the service, it complains about the connection manager already being registered.
Please advise. What am I doing wrong? I ultimately want each service to have its own schema, and each schema gets its own connection string. Within my RO for Delphi I imported the daConnection file when the server first stated, saving it as a TStringStream. Then simply grabbed that stream in the OnCreate of each service and imported into that services own CxnManager. I get the impression that with .NET only have ONE connection managers is allowed.
By default ConnectionManager registers itself as a singleton. However it exposes a constructor that accepts Boolean parameter that indicates whether ConnectionManager instance being created should be registered as singleton or not. So you need to create ConenctionManager passing false to its constructor.
Also please note the following:
Re-instantiation of ConnectionManager on each service call is very ineffective in terms of performance. It would be much better to cache ConnectionManager instances and retrieve needed instance when the service is activated.
In case all your services are exactly the same and only their Schema and ConnectionManager are different you could consider to use only one service and to select needed ServiceSchema and ConnectionManager when the service instance is activated.
The purpose of the BeforeAcquireConnection event is to allow to change name of the connection to be acquired. The connection itself is not yet acquired at the moment this event is triggered.
Acquired connection is available in the AfterAcquireConnection event.
I am not opposed to using the “singleton” instance of the connection manager in the main thread. But when I attempt to open a dataset from the client using the connection manager from the main thread, It complains with error: “No connection manager has yet been registered”.
The problem happens if there is no registered ConnectionManager component. You can put this component anywhere on the server side.
And when I use a new ConnectionManger in the IMPL file, I get an error regarding name length cannot be zero.
After setting ConnectionManager component it is necessary to load corresponding schema connections using the next code:
this.connectionManager.Load();
Then client will be able to get data from the server side.
I get {“Object reference not set to an instance of an object.”}
The connectionManager is not null. What am I doing wrong?
Also, I am needing to load the MyCxnMgr.daConnections, which I am doing using
this.connectionManager.LoadFromFile( MyFullPath + “\MTCxnMgr.daConnections”));
I assume I do this before the Load() ?
I believe I discovered the source of the problem. I modified the various aspects of the wizard created project to suite my fancy. In doing so, I modified the default daConnections project file from:
“WebSvcCCOK_B.daConnections"
to
"MTCxnMgr.daConnections”
This act raises the error I mentioned. So this begs the questions:
Where in the project is the connectionManager so closely bound to the unit named WebSvcCCOK_B.daConnections?
How do I change this relationship.
Further, IF… I were to use multiple CxnMgr, how are these each associated with different files.
Understand, that I am using the contents of WebSvcCCOK_B.daConnections only in design time, and wish to pull from a given file in runtime.
Also, it appears that after doing MyCxnMgr.LoadFromFile I do not need nor want to do MyCxnMgr.Load(), as it attempts to load the design time connections in addition to those from LoadFromFile, which is causing duplicates.
I believe I discovered the source of the problem. I modified the various aspects of the wizard created project to suite my fancy. In doing so, I modified the default daConnections project file from:
“WebSvcCCOK_B.daConnections”
to
“MTCxnMgr.daConnections”
Load method itself loads a Data Abstract connections file using the default mechanism, which looks in several places for a valid .daConnections file (Documentation | RemObjects Software):
as a .daConnnections file next to your application’s executable
as a .daConnnections resource in your application’s executable
If your application does not provide a custom DataAbstract.daConfig, either as file or as embedded resource, the call will fail with an exception.
So, as .daConnections file is renamed an exception is raised.
Where in the project is the connectionManager so closely bound to the unit named WebSvcCCOK_B.daConnections?
How do I change this relationship.
You need to use LoadFromFile(filepath) method instead which allows to get connection definitions from the specified file.
Further, IF… I were to use multiple CxnMgr, how are these each associated with different files.
Understand, that I am using the contents of WebSvcCCOK_B.daConnections only in design time, and wish to pull from a given file in runtime.
Using LoadFromFile(filepath) method you can set connection definitions dynamically setting different filepathes in runtime.
Also, it appears that after doing MyCxnMgr.LoadFromFile I do not need nor want to do MyCxnMgr.Load(), as it attempts to load the design time connections in addition to those from LoadFromFile, which is causing duplicates.
You don’t need to use Load() together with LoadFromFile() as they use the same .daConnections file to load. Please use LoadFromFile() instead.
Now that I am past that, I am next plagued with being unable to find a given schema. When I attempt to open a dataset from a client, the MT complains about being unable to find the given schema. So for example, I have a service called SvcQuote. In its IMPL I have defined its ServiceSchemaName as SvcQuote, to correspond with the unit SvcQuote.daSchema that is in the VisualStudio project. However the MT errors with “Cannot find schema SvcQuote”. I have tried naming the ServiceSchemaName = SvcQuote.daSchema. This has no effect.
Also, If I use MyCxnMgr.LoadFromFile vs MyCxnMgr.Load I get the exception "Length cannot be less than zero. Parameter name: length
Upon further digging, it appears this error stems from decrypting the password. If I don’t encrypt the password, then the LoadFromFile works. So… what in the following code is causing the length error?
for (i = 0; i <= this.daCxnMgr.ConnectionDefinitions.Count - 1; i++)
{
lCxnStr = this.daCxnMgr.ConnectionDefinitions[i].ConnectionString;
lbool = RemObjects.DataAbstract.Server.ConnectionStringParser.Parse
(lCxnStr
, out lDriverName
, out lProvInfo
, out lDBProfile
, out lParamList
);
lPWord = cRijndaelEncrypt.fxCrypt(lParamList[“PASSWORD”], false);
lParamList[“PASSWORD”] = lPWord;
lCxnStr = RemObjects.DataAbstract.Server.ConnectionStringParser.BuildProviderConnectionString(lProvInfo
, lDBProfile
, lParamList
);
this.daCxnMgr.ConnectionDefinitions[i].ConnectionString = lCxnStr;
}
Please advise.
How do I successfully load from a file, change the password in each connection string, then load to the manager?
How does one successfully reference a given schema? In Delphi, it was a simple matter of placing a daSchema on a service. In .NET there appears to be some other requirement. Because apparently ServiceSchemaName is insufficient.
Now that I am past that, I am next plagued with being unable to find a given schema. When I attempt to open a dataset from a client, the MT complains about being unable to find the given schema. So for example, I have a service called SvcQuote. In its IMPL I have defined its ServiceSchemaName as SvcQuote, to correspond with the unit SvcQuote.daSchema that is in the VisualStudio project. However the MT errors with “Cannot find schema SvcQuote”. I have tried naming the ServiceSchemaName = SvcQuote.daSchema. This has no effect.
The problem could happens if there is mismatching in ServiceSchemaName or schema is not present on the server side. If all is well in the project, can you send us testcase to investigate it in details?
Upon further digging, it appears this error stems from decrypting the password. If I don’t encrypt the password, then the LoadFromFile works. So… what in the following code is causing the length error?
Unfortunately, I can’t reproduce the problem locally. The code you have provided works on my side. Any additional information or testcase will be helpful to reproduce the problem locally and provide more concrete solution.
I suspect you will find that all though the code appears to work, when you attempt to open a datatable from a client, that you will get the error “Length cannot be less than zero. Parameter name: length”.
So to duplicate the problem, please take the code I provided, and attempt to open a query. Then you will see the error.
Thank you for the testcase. I have reproduced the problem. To solve it please change the line:
this.daCxnMgr.ConnectionDefinitions[i].ConnectionString = lCxnStr;
to:
this.daCxnMgr.ConnectionDefinitions[i].ConnectionString = String.Format("{0}?{1}",lDriverName,lCxnStr);