Setting Connection String through code without app.config/web.config

16 posts, 0 answers
  1. Chris Adler
    Chris Adler avatar
    1 posts
    Member since:
    Nov 2009

    Posted 03 Dec 2009 Link to this post

    I'm developing some components that are all DLL's. One of them will use the ORM features and needs to be able to access a database. I don't want to require that which ever application is using my components has a connect in their app.config file. What I'd like to do is when my code initializes programmatically connect to the database, or at least define the connection string via code, not by modifying a watched config file.

    Is this possible?
  2. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 04 Dec 2009 Link to this post

    Hi Chris,

    You should take a look at the AdjustForDynamicLoad method of your ObjectScopeProvider, since it will pass a code-crafted XML document to the Database.Get method, essentially ignoring the configs of whatever Assembly or Application is using your assembly.

    I have done this in this sample. I know it shows quite some more of what you asked, but if you focus on the Infrastructure assembly you will see that it holds a slightly modified ObjectScopeProvider.cs and a local app.config with the connection settings.
    The idea is that the database connection is encapsulated into this assembly, so users of the assembly does not need to care about it.

    Give it a whirl and let me hear what you think.

    Regards

    Henrik
  3. DevCraft banner
  4. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 04 Dec 2009 Link to this post

    Hello guys,

    In fact there is an easier way. You can obtain a database connection by passing a connection string to the Database.Get() method. The code would look like this if a mssql connection string is used:
    ConnectionStringSettings connSettings = new ConnectionStringSettings();
    connSettings.Name = "DatabaseConnection1";
    connSettings.ConnectionString = @"data source=(local)\sqlexpress;initial catalog=Northwind;integrated security=True";
    connSettings.ProviderName = "System.Data.SqlClient";
     
    BackendConfiguration backendConfig = new BackendConfiguration();
    backendConfig.Name = "mssqlConfiguration";
    backendConfig.MappingName = "mssqlMapping";
     
    Database db = Database.Get(connSettings, backendConfig);
     
    IObjectScope scope = db.GetObjectScope();

    However, it is required that the mssqlMapping is specified in the config file. The connection string there can be wrong (see the config below), but the <backendconfiguration> and <mapping> nodes should be specified correctly. When executing the code above, the connection string passed to the Get() method will be respected. Note that there should not be a connection string with the same name in the global <connectionStrings> section.
    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <section name="openaccess" type="Telerik.OpenAccess.Config.ConfigSectionHandler, Telerik.OpenAccess.Config, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7ce17eeaf1d59342" requirePermission="false" />
      </configSections>
      <connectionStrings />
      <openaccess xmlns="http://www.telerik.com/OpenAccess">
        <references />
        <connections>
          <connection id="DatabaseConnection1">
            <connectionString>Data Source=(LOCAL)\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True</connectionString>
            <backendconfigurationname>mssqlConfiguration</backendconfigurationname>
          </connection>
        </connections>
        <backendconfigurations>
          <backendconfiguration id="mssqlConfiguration" backend="mssql">
            <mappingname>mssqlMapping</mappingname>
          </backendconfiguration>
        </backendconfigurations>
        <mappings current="mssqlMapping">
          <mapping id="mssqlMapping">
          </mapping>
        </mappings>
      </openaccess>
    </configuration>

    Best wishes,
    Alexander
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  5. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 06 Dec 2009 Link to this post

    Hi Alexander,

    Thank you for joining us and thanks for elaborating on this. I can see that one does not have to think about xml, since there are classes that encapsulate the xml in the config.
    But will it still solve the encapsulating problem that Chris had?

    Regards

    Henrik
  6. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 07 Dec 2009 Link to this post

    Hello Henrik,

    Yes, I believe this will work for him. With the old OpenAccess' connection settings there was no way to override just the connection at runtime and the whole xml configuration had to be constructed in memory. Now due to the connection string support (introduced in Q3) it is possible to override the connection string but use the rest of the configuration from the xml file. So it does not matter what connection string is specified in the .config file as long as the correct one is specified at runtime.

    Greetings,
    Alexander
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. TSE
    TSE avatar
    381 posts
    Member since:
    Sep 2008

    Posted 07 Dec 2009 Link to this post

    Hi Alexander,

    Great.. Thanks for your quick answers.

    /Henrik
  8. Dan
    Dan avatar
    35 posts
    Member since:
    Oct 2008

    Posted 13 Jan 2010 Link to this post

    Alexander-

    I'm trying to implement the code you posted in the last release of OpenAccess (2009.3.1119.2), but Database.Get() only appears to have 3 overloads and they all begin with a string connectionId.  Is this in a newer build or removed?  Also, under what namespace is the BackendConfiguration class?  Thanks.

    Lars
  9. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 15 Jan 2010 Link to this post

    Hello Lars,

    It is my fault, I was testing this on my dev machine where the code is available. However, it is not in the product yet. I am very sorry for misleading you, this functionality will be available in the Q1 2010 release. In the meantime you will have to use the old approach - overriding the configuration nodes dynamically.
    To do this, you can extend a bit the AdjustForDynamicLoad() method of the ObjectScopeProvider so it accepts a connection string and replaces the <connection> node from the configuration file. Then this method should be called before obtaining the first IObjectScope instance from the ObjectScopeProvider. The code would look similar to this:
    static public void AdjustForDynamicLoad(string connectionString)
    {
        if( theObjectScopeProvider1 == null )
            theObjectScopeProvider1 = new ObjectScopeProvider1();
     
        if( theObjectScopeProvider1.myDatabase == null )
        {
            string assumedInitialConfiguration =
     
                       "<openaccess>" +
                       "<connections>" +
                          "<connection id='DatabaseConnection1'>" +
                            "<connectionString>CONNECTIONSTRING</connectionString>" +
                            "<backendconfigurationname>mssqlConfiguration</backendconfigurationname>" +
                          "</connection>" +
                        "</connections>" +
                       "<references>" +
                           "<reference assemblyname='PLACEHOLDER' configrequired='True'/>" +
                       "</references>" +
                   "</openaccess>";
     
            System.Reflection.Assembly dll = theObjectScopeProvider1.GetType().Assembly;
            assumedInitialConfiguration = assumedInitialConfiguration.Replace(
                                                "PLACEHOLDER", dll.GetName().Name);
            assumedInitialConfiguration = assumedInitialConfiguration.Replace(
                                                "CONNECTIONSTRING", connectionString);
            System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
            xmlDoc.LoadXml(assumedInitialConfiguration);
            Database db = Telerik.OpenAccess.Database.Get("DatabaseConnection1",
                                        xmlDoc.DocumentElement,
                                        new System.Reflection.Assembly[] { dll } );
     
            theObjectScopeProvider1.myDatabase = db;
        }
    }

    The App.config does not have to be changed. Just make sure that you do not have a connection string with the same name (DatabaseConnection1 in our case) in the global <connectionStrings> section because it cannot be overridden by the AdjustForDynamicLoad method and the solution above would not work. Hope that helps.

    Kind regards,
    Alexander
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  10. Andre' Hazelwood
    Andre' Hazelwood avatar
    12 posts
    Member since:
    Oct 2005

    Posted 27 Jan 2010 Link to this post

    Just a clarification: 

    Will the upcoming Q1 release allow us to pass in a connection string (either referencing what is in web.config's connectionstrings, or from some other source - i.e. a Connection DSN defined in a database table)?  Also any idea of when the Q1 release will be coming out?

    Thanks,
    Andre'
  11. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 29 Jan 2010 Link to this post

    Hi Andre' Hazelwood,

    Yes, you will be able to pass a connection string (or a connection string name) directly in the code to obtain a connection. The release is scheduled for the first half of March.

    Best wishes,
    Alexander
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  12. Myth
    Myth avatar
    54 posts
    Member since:
    Jan 2010

    Posted 28 May 2010 Link to this post

    Hello,

    Has this been implemented yet? Because the code example that was given earlier still doesn't seem to work.

    Thanks in advance,
    Stijn
  13. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 28 May 2010 Link to this post

    Hello Myth,

    This API has gone through some changes and is a bit different from what I posted some months ago. Nevertheless, I am afraid that this API is available only for OpenAccessContext classes, i.e. for contexts generated by the DSL designer and cannot be used with object scopes.
    In the constructor of such OpenAccess context you can pass directly either a connection string name or a whole connection string. In case of passing a connection string, additional parameters are required to specify the backend type and the mapping source. Here is an example:
    string connectionString = @"data source=.\sqlexpress;initial catalog=AdventureWorks;integrated security=True";
    BackendConfiguration backendConfig = new BackendConfiguration() { Backend = "mssql" };
    MetadataSource metadataSource = XmlMetadataSource.FromAssemblyResource("EntityDiagrams1.rlinq");
     
    AdventureWorksEntityDiagrams ctx = new AdventureWorksEntityDiagrams(connectionString, backendConfig, metadataSource);

    Kind regards,
    Alexander
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  14. naru
    naru avatar
    11 posts
    Member since:
    Sep 2010

    Posted 09 Sep 2010 Link to this post

    Hello everyone,

    I have a question that I think I may add to this thread… I’m specifying the connection string at runtime, based on a global web.config file (I’m working on one of a project’s several modules).

    I followed the help article (the 2nd scenario):
    http://www.telerik.com/help/openaccess-orm/openaccess-tasks-howto-dinamically-manage-connection.html

    So I use the AdjustForDynamicLoad to build the entire configuration xml on runtime, using the global web.config file.
    I maintained the original App.config, although its content is overridden once the AdjustForDynamicLoad function is run, so the correct configuration is used by the application.

    The help article is great, and I got everything working well, but I noticed a few aspects:

    -   During the Solution Build, the dummy database, which I left specified in the App.config, is created, and tables are created for it too! (In the application run, the dummy database is not used, but the correct one is.)

    -   I cannot delete the App.config file, or leave the content of the xml tags blank, as I will get an unsuccessful build with an OpenAcess Error.

    Basically, I would like to build and run the application, without the App.config file, or with the file’s contents blank (I don’t want at all the dummy databases to be created!). Perhaps I’m missing a reference, or should do some adjustments on the ObjectScopeProviders.cs’s functions that could solve this.

    Any suggestions are appreciated. Thanks in advance!
  15. naru
    naru avatar
    11 posts
    Member since:
    Sep 2010

    Posted 09 Sep 2010 Link to this post


    Okay, it was an easy solution:

    http://www.telerik.com/help/openaccess-orm/project-properties.html

    Delete the "App.config" in the classy library's ConfigFile property. Then delete the original App.config file (created when enabling the project), and so far the solution is building and running.
  16. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 10 Sep 2010 Link to this post

    Hello naru,

    You can also try disabling the UpdateDatabase option of the class library. I guess this option is enabled for your project and that is why a dummy database is created on build.

    Best wishes,
    Alexander
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  17. naru
    naru avatar
    11 posts
    Member since:
    Sep 2010

    Posted 15 Sep 2010 Link to this post


    Hello Alexander,

    Thank you for your suggestion, and for your quick reply. I checked and actually, the class library has had the UpdateDatabase = false... The solution however, had this property set to true recently, so due to that the database was being generated.

    In this case, the solution still needed the ConfigFile to be set to empty. While attempting to read it, if it wasn't able to access nor create the dummy database (lack of permissions, UpdateDatabase = false,...), the application would not run. And I wanted the application to disregard any configuration files, because I have the configuration being generated on run time (thanks to the Dynamically Manage a Connection to a Data Store help article!).

    Now I've got the class library:
    ConfigFile: App.config
    UpdateDatabase: false

    And the solution and other projects:
    ConfigFile:
    UpdateDatabase: false

    and everything is running nicely.
Back to Top
DevCraft banner