System.data.SQLite entity framework code first programmatic providername specification - c#

I've spent a while on this now and have only found a workaround solution that I'd rather not do...
I have a context as shown below. Is there a programmatic way to specify the database to connect to via the constructor, and get it to use the System.Data.SQLite entity framework provider to connect to a SQLite database? This is working via the app.config (with a connectionstring called "Context"), but not via any programmatic way I can find of supplying it. I have tried using an entity connectionstring builder and that produces the following string:
provider=System.Data.SQLite;provider connection string='data
source="datafile.db"'
When the context is first queried with this string I get a message "Keyword not supported: 'provider'."
public class Context : DbContext
{
public IDbSet<Test> Tests { get; set; }
public Context()
: base("Context")
{
}
}
*Edit.
I may have solved this by implementing my own connectionfactory:
public class ConnectionFactory : IDbConnectionFactory
{
public DbConnection CreateConnection(string nameOrConnectionString)
{
return new SQLiteConnection(nameOrConnectionString);
}
}
Then setting:
Database.DefaultConnectionFactory = new ConnectionFactory();
However, it seems like there should be a built in way to do this, and also one that does not involve overriding the global default connection factory.

Related

Change DB name for Entity Framework DbContext

I have inherited an application which is using Entity Framework to access a SQL Server database. The DbContext class has the constructor as shown below, where BuildingPermits is the name of the initial catalog.
I would like to be able to switch between databases (with the same connection) via a config file instead of changing the code.
How can I accomplish this?
public BuildingPermitsDbContext() : base("BuildingPermits")
{
Database.SetInitializer<BuildingPermitsDbContext>(null);
}
You can try this.
using System.Configuration;
public BuildingPermitsDbContext() : base(DatabaseName())
{
Database.SetInitializer<BuildingPermitsDbContext>(null);
}
private static string DatabaseName()
{
var db = ConfigurationManager.AppSettingss["desiredDbName"];
return db;
}

How to create a DbContext instance of the specified database type

I know that the default return here is the SQL Server database type, but I need the MySQL database type, the problem is to create a DbContext instance of the specified database type?
Of course, I know that it can also be created by specifying the connectionName, but the database connection string is encrypted and the string needs to be decrypted
The pseudo code is as follows:
public partial class MyDbContext : DbContext
{
static string mysqlConn = ReadConnectionString(); //Get the encrypted MySQL connection string
public MyDbContext() : base(mysqlConn)
{
// Even if I want to modify the connection string in this way, nor will it throw a connection string malformed exception
Database.Connection.ConnectionString = DecryptConnectionString(mysqlConn);
}
}
Ok, it's about what I expected, few of my questions can be answered.
Although I am not too familiar with EntityFramework, by looking at the source code of DbContext, I can almost certainly determine that this is a design flaw, it lacks a constructor like this:
Public DbContext(string connectionString, string providerName)
I had same problem and found .Net framework 4.5 needs additional attribute on DbContext class to use MySql as below
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class MySqlContext : DbContext
{
...
}

C# .NET Entity Framework multi-tenant best practice

Consider the following code segment:
public class DatabaseContext : DbContext
{
public DatabaseContext(String connectionString) : base(connectionString)
{
}
}
public class ContextNameDatabaseContext : DatabaseContext
{
public ContextNameDatabaseContext(String connectionString) : base(connectionString)
{
}
}
Would one say it is best practice when building the back-end for a multi-tenant solution where each client has its own database and maintain the data state until a user logs out / off?
Developer using these classes in this instance will need to be aware and careful as to when and how the classes are being used where the 'DatabaseContext' class acts as a base to the 'ContextNameDatabaseContext' class.
Please advise on any thoughts or suggestions.
One approach is to keep all the database connection strings as parameters in the database. However you have to assure that its encrypted.
Then at your DB layer you can pass the connection as parameter in plain text after decrypting and constructing your connection string accordingly:
public class MyDatabase: DbContext
{
public MyDatabase(string connString)
{
this.Database.Connection.ConnectionString = connString;
}
public DbSet<Order> Orders{ get; set; }
}
You can also use IOptions if you are using .NET Core to inject the connection string as a dependency.

Configuring DbContext Constructor

I'm trying to use EF Core tools to manage an SqlServer database I'm designing in a C# class library. It's in a class library because I need to use the database schema in both an MVC6 website and some command line tools.
I had to convert the class library to being a netapp because the current version of the tooling doesn't support class libraries, but I don't think that's the source of my problem.
My DbContext class looks like this:
public class ConnellDbContext : IdentityDbContext<ConnellUser>
{
public ConnellDbContext( DbContextOptions<ConnellDbContext> options )
{
}
// core tables
public DbSet<Ballot> Ballots { get; set; }
public DbSet<Campaign> Campaigns { get; set; }
//...
}
When I run "dotnet ef migrations list" on the Package Manager Console, I get the following error message:
No parameterless constructor was found on 'ConnellDbContext'. Either
add a parameterless constructor to 'ConnellDbContext' or add an
implementation of 'IDbContextFactory' in the same
assembly as 'ConnellDbContext'.
I'm not quite sure how to resolve this. It's easy enough to insert a parameterless constructor, but when I do I get the following error:
No database provider has been configured for this DbContext. A
provider can be configured by overriding the DbContext.OnConfiguring
method or by using AddDbContext on the application service provider.
If AddDbContext is used, then also ensure that your DbContext type
accepts a DbContextOptions object in its constructor and
passes it to the base constructor for DbContext.
I >>think<< this means the console commands are not picking up the connection string information in my appsettings.json file:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-ConnellCampaigns;Trusted_Connection=True;MultipleActiveResultSets=true;AttachDbFilename=e:\\SqlServer\\Data\\ConnellCampaigns.mdf;"
}
}
I'm missing something about how the EF tooling accesses the source code to do its magic. Any pointers or leads would be much appreciated.
Additional Info
Thanx to Mr. Anderson I've made a bit of progress. I added a parameterless constructor and overrode the OnConfiguring() method in my DbContext class:
protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder )
{
var builder = new ConfigurationBuilder()
.AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true );
IConfigurationRoot config = builder.Build();
optionsBuilder.UseSqlServer(config.GetConnectionString("DefaultConnection") );
}
That didn't work, but explicitly including the actual connection string in the call to UseSqlServer() did. Thoughts on why the call based on "DefaultConnection" didn't work?
public class ConnellDbContext : IdentityDbContext<ConnellUser>
{
internal static string connection_string
{
get
{
return System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
}
}
public ConnellDbContext() : base(connection_string)
{
}
// core tables
public DbSet<Ballot> Ballots { get; set; }
public DbSet<Campaign> Campaigns { get; set; }
//...
}

How to use dynamic connection string for SQL Server CE?

I used SQL Server CE 4.0 in my windows app and use Entity Framework to create a model of it.
It works fine but my problems is that it doesn't have a constructor to change the connection string, and by default it reads the connection string from the app.config file.
using (var Context = new MyEntitiesModel(//has no constructor))
{
...
}
I create a dynamic connection string and
using (var Context = new MyEntitiesModel())
{
Context.Database.Connection.ConnectionString = entityConnection.ConnectionString;
}
It works fine by this way but if I remove another connection string in app.config file it gave me this.
error = invalid metasource ....
because the default constructor uses it
How can I handle it?
Create your own constructor. MyEntitiesModel is partial class you can add your own partial part of the class and add constructor accepting a connection string.
public partial class MyEntitiesModel {
public MyEntitiesModel(string connectionString) : base(connectionString) { }
}
Im using DbContext. There are several Overload Constructors eg:
ObjectContext also has a similar set of constructor overloads.
System.Data.Entity DbContext example
Context = new BosMasterEntities(nameOrConnectionString: nameOrConnectionString);
You can connect to multiple Dbs at same time.

Categories