In our ASP.NET Core and EF Core system, we use different databases for different parts of the system. I need to be able to tell, at runtime, which db provider is being used, because some stuff needs to take this into account.
During startup, there is this for SQL Server:
services.AddDbContext<MyContext>(
options => options.UseSqlServer(config.GetConnectionString("DefaultConnection"))
);
or this for SQLite:
services.AddDbContext<MyContext>(
options => options.UseSqlite(config.GetConnectionString("DefaultConnection"))
);
The point being that the knowledge of which database is being used, is contained within the system, somewhere.
At some arbitrary point in the system, how can I determine which database I'm using? I have access to the MyContext
. Is there something in there that can reveal this info?
I use in my project 3 database providers.
Not used in my project. Update. June 17, 2020. I noticed that the Oracle Provider has an extensión method IsOracle.
Include in your client project, any of those references, can be added from Nuget Package manager or CLI.
The references contains the following extension methods.
Boolean isPostgreSQL = context.Database.IsNpgsql();
Boolean isSqlServer = context.Database.IsSqlServer();
Boolean isMySql = context.Database.IsMySql();
Boolean isOracle= context.Database.IsOracle();
Example 1
public static EntityTypeBuilder<TEntity> ToTable<TEntity>(this EntityTypeBuilder<TEntity> builder, string schema, DatabaseFacade database) where TEntity : class
{
switch(database)
{
case DatabaseFacade db when db.IsMySql():
builder.ToTable($"{schema}.{typeof(TEntity).Name}");
break;
case DatabaseFacade db when db.IsSqlServer() | db.IsNpgsql():
builder.ToTable(typeof(TEntity).Name, schema);
break;
default:
throw new NotImplementedException("Unknown database provider.");
}
return builder;
}
Example 2
private static string GetEffectiveConstraintName(string name, DatabaseFacade database)
{
return database switch
{
DatabaseFacade db when db.IsSqlServer() => name,
DatabaseFacade db when db.IsNpgsql() => name.Length < DataAccessConstants.PostgreSqlIdentifierMaxLength ? name : name.Substring(0, DataAccessConstants.PostgreSqlIdentifierMaxLength),
DatabaseFacade db when db.IsMySql() => name.Length < DataAccessConstants.MySqlIdentifierMaxLength ? name : name.Substring(0, DataAccessConstants.MySqlIdentifierMaxLength),
_ => throw new NotImplementedException("Unknown database provider")
};
}
Anywhere in the system, where you have access to the MyContext
, do this:
context.Database.GetDbConnection().GetType().Name
For example, it is SqliteConnection
for SQLite, or SqlServerConnection
for SQL Server, etc.
However I'm not sure if you'll need to dispose the connection afterwards!
I'm not sure if there is a public way of doing it, but you can look at context.Database.DatabaseCreator (you'll have to use reflection to get to DatabaseCreator), but by looking at the type, you can tell what kind of connection it is. For example, with SQL, you'll get SqlServerDatabaseCreator.
EDIT: Yeah, looking at the code, I don't think there is any other way to tell besides what I mentioned above. The UseSqlServer method doesn't set any flags anywhere or anything like that. It's just a factory.
For EF Core 2:
dbContext.Database.ProviderName
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With