32

When you derive from DbContext and use the parameter-less constructor it will load a connection string from web.config. You also have the option of explicitly specifying the connectionString using one of the other DbContext constructors.

My particular situation dictates that the connection string CANNOT be specified in the web.config, as the location of the server/username and password are determined at runtime. Easy fix right? Just use the above mentioned constructor to specify the connection string? Wrong.

The problem is that when you specify the connection string using said constructor, it still attempts to use the default provider, so if you're using one or more non standard providers, as I am, it will not work.

I'm sure I can change the default provider in the web.config, but I want to use multiple providers so this will not do.

The only possible way around this that I can see is to use ObjectContext instead of DbContext, which seems to allow you to specify the provider along with the database connection string.

Is there any other way to do it? Is my workaround fairly reasonable?

I believe I can also create a DbContext from an ObjectContext instance.

NoPyGod
  • 4,905
  • 3
  • 44
  • 72
  • 1
    You could use the constructor that takes a `DbConnection`. – Gert Arnold Jul 01 '13 at 08:31
  • My concern with that is that I'd then be managing the life of the DbConnection myself. I'm also not entirely sure how I create the DbConnection using a specific provider. – NoPyGod Jul 01 '13 at 08:33

3 Answers3

37

Create your DbConnection manually and pass it to the DbContext constructor as follows:

var conn = DbProviderFactories.GetFactory("MY_CONN_PROVIDER").CreateConnection();
conn.ConnectionString = "MY_CONN_STR";

new DbContext(conn, true);

Notice the second parameter bool contextOwnsConnection is true. Since you don't re-use the connection elsewhere, it lets the context manage the connection and Dispose() it when needed.

haim770
  • 48,394
  • 7
  • 105
  • 133
  • is it possible to use just **one line** instead of above **3** lines, to initialize a FooDbContext? because those lines will be used repeatedly: `using context = new FooDbContext()...` – Lei Yang Apr 27 '20 at 04:39
0

You can get to the ObjectContext through IObjectContextAdapter:

((IObjectContextAdapter)context).ObjectContext

DbContext ("context" above) still wraps ObjectContext, so don't worry that you will have a new instance.

You can instantiate DbContext using this overload

public DbContext(ObjectContext objectContext, bool dbContextOwnsObjectContext) {}

for example:

public class YourDbContext : DbContext 
{
    public YourDbContext() : this(new YourObjectEntities(), dbContextOwnsObjectContext: true) 
    {}

}

Then you can set your connection string inside of YourObjectEntities:

public partial class YourObjectEntities : ObjectContext
{
    public const string ConnectionString = "name=YourEntities";  // Get it from somewhere

    public YourObjectEntities() : base(ConnectionString, "YourEntities")
    {
    // Some initialization, e.g. ContextOptions.LazyLoadingEnabled = false;
    }
}

How you specify the provider there is your exercise.

Andrei Drynov
  • 8,362
  • 6
  • 39
  • 39
-2

Try like this ,

public DBDataContext _dataContex;

public DBDataContext DBContext 
    {
        get
        {
            if (_dataContex== null)
            {
                _v= new DBDataContext(ConfigurationManager.ConnectionStrings["yourConnectinString"].ConnectionString);
            }
            return _dataContex;
        }

    }
zey
  • 5,939
  • 14
  • 56
  • 110
  • 1
    Nope, I'd already tried that. Like I said, it tries to use the default provider. -- I tried again just to be sure - ProviderIncompatableException. – NoPyGod Jul 01 '13 at 21:30