How to use dynamic connection string for SQL Server CE? - c#

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.

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
{
...
}

Using multiple connection strings for the same DBContext

I am working on a asp.net core project which uses MongoDB and I am using dependency injection as well.
How current system works
There is only one database and the connection string is saved in the appsettings.json. Some devices will be constantly sending data through the API to save it in the MongoDB database which works as it should :)
Now I have to enhance it, there will be multiple databases and data should be saved in the relevant database based on the API request (i will be getting the database name in the API request).
My question is how that can I change the database based on the API request? while using the same DbContext. It is not an option to create multiple DbContext.
I am somewhat new to MongoDb and asp.net core so any help or guidance is much appreciated.
This is my DbContext class
public class DbContext
{
private IMongoDatabase _database;
protected readonly MongoClient mongoClient;
public DbContext(MongoSetting dbConnSettings)
{
var mongoUrl = new MongoUrl(dbConnSettings.ConnectionString);
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
mongoClient = new MongoClient(mongoClientSettings);
if (mongoClient != null)
_database = mongoClient.GetDatabase(dbConnSettings.database);
}...
Section of my StartUp class
services.AddTransient<CareHomeContext>();
services.AddSingleton(provider => provider.GetService<IOptions<MongoSetting>>().Value);
If I understand your usecase correctly, it might be needed to use different databases in each request as well.
Hence I suggest to make database name as an optional parameter (so that you can use a default value from the configuration in case the database name is not provided in the request) to the DbContext class methods and create a method to get the database object (instead of getting it in the constructor) in the DbContext class as below.
private IMongoDatabase GetDatabase(string databaseName) => mongoClient.GetDatabase(databaseName ?? defaultDatabaseName);
Invoke the above method in each DbContext class method. e.g.
public async Task InsertAsync(string collectionName, Dictionary<string, object> fields, string databaseName = null) {
var database = GetDatabase(databaseName);
// Insert Code here
}
I hope this would help.

Connect to Sqlite database at run time using entity framework

I want to connect my project to an Sqlite database. So, in my Database Context I have this cunstructor and an Initialize method
private DatabaseContext(string cnxString) : base(cnxString)
{
Database.SetInitializer<DatabaseContext>(new DatabaseInitialiser());
}
public static void initialize(string connx)
{
_instance = new DatabaseContext(connx);
}
and In the program.cs I call Inialize method to set the connexion string
DatabaseContext.initialize("data source=D:\storage.sqlite;");
So, every user can connect to his database by passing his connexion string.
But, when running my application I have this error :
An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct.
You'll need to pass in a SQLite connection object to the base constructor:
private DatabaseContext(string cnxString)
: base(new SQLiteConnection(cnxString), contextOwnsConnection: true)
{
}

System.data.SQLite entity framework code first programmatic providername specification

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.

Categories