Passing Connection String Dynamically While Using a Model First Approach

Hello Friends.

Note: the following article will help you in these scenarios:

  1. You have created a class library test project and want to access the database using the ADO.NET Entity Data Model.
  2. You have another class library project that needs database access, but for some reason, you don't have another project that is set as the startup project in your solution.  I've been looking at the Telerik's Test Studio for a few days now. This is my first attempt at automated testing.

As with any other functional testing, I soon realized the need for accessing a database from within my test project to write test validations against database values.

And, here is the issue.

When you export a Telerik test project to Visual Studio, you will notice that the project is basically a class library project. Now in order to access the database, I quickly added an ADO.Net Entity Data Model (.edmx file) to my project.

Adding the data model auto-magically adds a new App.Config file in the project that has the connection string details.

Now if you are using this class library project along with other projects in your solution, which is the startup project for your solution, this all works fine and your class library project will be able to find the connection string in the App.config file.

But in my case, this class library project is basically a Test project. So I don't need to compile it to run/debug a single test case. All I need to do is to right-click on one of my test cases in the Test Explorer and Telerik's ArtOfTest.Runner.exe will invoke that, load the test cases and start executing it.

So the app.config of the project is never loaded and thus I get an error when the DB query is fired.

MRM_LatestEntities context = new MRM_LatestEntities();
var items= context.Categories.AsQueryable();

The error I get is "No Connection String "MRM_LatestEntities" was found in Application Configuration File" and the reason was pretty obvious. My test project is not aware of the app.config file at all, forget about loading and using it.

In order to solve this, this is what I had to do:

  1. Create an overloaded constructor in the DataModel.Context.cs file; mine is called testDataModel.Context.cs, as in the following:

    public MRM_LatestEntities(string sqlServerConnectionString)
    : base(sqlServerConnectionString)
    {
    }

    The default constructor looked like, this would attempt to retrieve the connection string from the app.config file:

    public MRM_LatestEntities()
    : base("name=MRM_LatestEntities")
    {
    }
     
  2. Obtain your App.Config file in code, as in the following:

    //get connection string
    Assembly me = Assembly.GetExecutingAssembly();
    Configuration config = ConfigurationManager.OpenExeConfiguration(System.IO.Path.Combine(this.ExecutionContext.DeploymentDirectory, "Bin\\Debug\\", me.ManifestModule.Name));

    Note:

    I. If you are in Visual Studio 2010 you will not need the second parameter ("Bin\\Debug\\",) and you can do away with it. This is because of a change that was made in Visual Studio 2012.
    II. You will need to add references to System.Reflection and System.Configuration.
     
  3. Obtain the connection string from the App.config file, as in the following:

    string conn = config.ConnectionStrings.ConnectionStrings["MRM_LatestEntities"].ConnectionString;
     
  4. Finally, pass this connection string to the newly created parameterized constructor, as in the following:

    MRM_LatestEntities context = new MRM_LatestEntities(conn);
    var items= context.Categories.AsQueryable();
    var count = items.Count();

    And this time you will not get an error and will get the results as expected.

Hope this helps.

Enjoy Coding!!