2

I am creating an application which uses Entity Framework; specifically, Database First.

When the user logs in, a ConnectionString is created at run-time which is then intended to be used for any data handling in the application.

I have already found a number of solutions to this on the Internet which suggest that the way to do this is to implement another constructor for the DbContext class which is created which calls the base DbContext(string):

public ApplicationDbContext(SqlConnection Connection)
            : base(Connection.ConnectionString)
        {
        }

This, I have created in a separate file which is a public partial class of the generated code, to account for any further generated code overwriting what's already in those files.

However, when the application is running, as soon as an ApplicationDbContext is created using this additional constructor, the following exception is raised:

"The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development..."

This would make sense as I'm using a Database first approach. However, all of the answers I have seen where Database First is used suggest doing this.

Having looked into it a little further on MSDN, I see that there is actually another DbContext constructor that I could use: DbContext(String, DbCompiledModel). I am wondering whether this is what I am missing and this is the constructor I need, since I would have said I am using a compiled model (...or am I?).

However, is this the correct way to approach it or does this need to be handled another way?

Your_Unequal
  • 246
  • 1
  • 5
  • 17
  • [Connecting to database for Multi-Tenant application?](http://stackoverflow.com/questions/32717832/connecting-to-database-for-multi-tenant-application) – Reza Aghaei Jun 09 '16 at 00:13
  • Thanks for the feedback; however I've tried constructing the ConnectionString in this manner and I am still getting the same error. I checked the format of the ConnectionString in App.config in order to replicate the same parameters that are in the ConnectionString which is used by default however, when I try and construct the ConnectionString using this data, I get an error 'keyword not supported' for 'provider', 'connectionstring' and for 'provider connection string'. Removing these at least allows the string to be constructed but as I say, that just results in the original error again. – Your_Unequal Jun 09 '16 at 09:29
  • The problem is in the connection string which is passed to the constructor. – Reza Aghaei Jun 09 '16 at 10:44

2 Answers2

2

First add a constructor overload to your context class to accept a string as connection string:

public TestDBEntities()
    : base("name=TestDBEntities")
{
}
public TestDBEntities(string connectionString)
    : base(connectionString)
{
}

Then use the connection string in your app.config or web.config. You should replace &qout; with " also you should include metadata=... and the connection should be in such format:

var cn = @"metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;" +
         @"provider=System.Data.SqlClient;" +
         @"provider connection string=""" +
         @"data source=(localdb)\v11.0;" +
         @"initial catalog=TestDB;" +
         @"integrated security=True;" +
         @"MultipleActiveResultSets=True;" +
         @"""";
var db = new TestDBEntities(cn);

Note: It's better to put the new overload in a partial class. Then it will not be touched each time when .tt template of context run.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Ah I see, I was missing the metadata from the string. I'm sure I'm getting somewhere as it's now telling me "Format of the initialization string does not conform to specification starting at index 159.". Having looked at the string in an outside viewer, position 159 is the start of 'provider connection string'. I will look into it further and try and find out why this is happening. – Your_Unequal Jun 09 '16 at 17:11
  • Paste your connection string from `appconfig` here. – Reza Aghaei Jun 09 '16 at 17:20
  • The full line from the config file is as follows. Note that I've replaced username and password with generic terms, just because :-) : name="KCAdminContext" connectionString="metadata=res://*/DataEntity.KCAdminEntities.csdl|res://*/DataEntity.KCAdminEntities.ssdl|res://*/DataEntity.KCAdminEntities.msl;provider=System.Data.SqlClient;provider connection string="data source=ALICE\MSSQL2014;initial catalog=KCADMIN_TEST;user id=USER_NAME;password=PASSWORD;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" – Your_Unequal Jun 09 '16 at 17:26
  • Here is exact connection string which you should use: `var cn = @"metadata=res://*/DataEntity.KCAdminEntities.csdl|res://*/DataE‌​ntity.KCAdminEntities.ssdl|res://*/DataEntity.KCAdminEntities.msl;provider=System‌​.Data.SqlClient;provider connection string=""data source=ALICE\MSSQL2014;initial catalog=KCADMIN_TEST;user id=USER_NAME;password=PASSWORD;MultipleActiveResultSets=True;App=EntityFramework‌​""";` – Reza Aghaei Jun 09 '16 at 17:35
  • Pay attention, you should create an overload for constructor which accepts `string`. Like I did in the answer. – Reza Aghaei Jun 09 '16 at 17:36
  • That connection string didn't quite work but after a bit of tweaking and testing (and by tweaking I mean just starting again using the App.config connection string like you suggested and gradually substituting in the dynamic values) I have now got it working; I had already created the overload as you'd said and placed it in a partial class to avoid any code regeneration wiping it; many thanks for your help! – Your_Unequal Jun 09 '16 at 22:59
  • Good job! happy to hear that you solved the problem! – Reza Aghaei Jun 09 '16 at 23:46
0
    public partial class DataBaseEntities : DbContext
    {
        //public DataBaseEntities()
        //    : base("name=DataBaseName")
        //{
        //}

        public DataBaseEntities()
            : base(ConstValues.ConnectionString)
        {
        }
     }

    public class ConstValues
    {
        public const string ConnectionString = @"metadata=res://*/EntityModel.DataBaseName.csdl|res://*/EntityModelDataBaseName.ssdl|res://*/EntityModel.DataBaseName.msl;provider=System.Data.SqlClient;provider connection string="";data source=.;initial catalog=DataBaseName;user id=mhhfghd;password=12345679;MultipleActiveResultSets=True;App=EntityFramework"";";
    }

you must replace &quot to "

Diako Hasani
  • 1,384
  • 13
  • 14