protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySql(#"server=localhost;port=3306;database=shopDb;user=root;password=mysql123;");
}
I am trying to connect entity framework and mySQL. Why i get this error? (Cannot convert 2 arguments from 'string' to 'MicrosofEntityFrameworkCore.ServerVersion')
code
You have an error in your connection string. Try to remove a port since you are using a local host.
Related
I am building my first application using .Net 6 EF Core.
I want to use the code-first method.
When I try to migrate using Update-Database (after I get this error:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server. The server was not found or
was not accessible. Verify that the instance name is correct and that
SQL Server is configured to allow remote connections. (provider: Named
Pipes Provider, error: 40 - Could not open a connection to SQL Server)
I have a "local instance of MySQL80" running on my machine. I can connect to it, using a DB tool, like Dbeaver or the MySQL Workbench.
This is the Connection String I am using:
"ConnectionStrings": {
"DevConnection": "Server=localhost;Database=my-desired-db-name;Trusted_Connection=True;"
}
This is my Program.cs:
using Microsoft.EntityFrameworkCore;
using react_chores_prototype_api.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<MyDBContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DevConnection")));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();
I know that this question came up a few times already, but I cant find a solution with the given explantations, also because of lots of different versions over the years. If someone can maybe help me, so i can start working on my project, that would be greatly appreciated.
EDIT:
I installed Pomelo MySql Provider and changed the connectionString to a mysql one.
Also i changed my Program.cs like this:
var conString = "Server=localhost;Database=my-db-name;Uid=root;Pwd=verySecurePw;";
builder.Services.AddDbContext<MyDBContext>(options => options.UseMySql(connectionString: conString, ServerVersion.AutoDetect(conString)));
Now it seems to work, I just get following SQL Syntax Error (Not really related to the original Question I guess):
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'NOT NULL,
Description nvarchar(200 NOT NULL,
Points int NOT NULL,
Related to this Model:
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace react_chores_prototype_api.Models
{
public class Task
{
[Key]
public int Id { get; set; }
[Column(TypeName = "nvarchar(50)"]
public string Name { get; set; }
[Column(TypeName = "nvarchar(200)"]
public string Description { get; set; }
public int Points { get; set; }
}
}
I'm using Pomelo Entity framework core with MySqlConnector in my asp.net 5 app to connect to my MySql database - using custom DbContext classes. This normally works fine.
However, I have a need to connect to another database than the one in the connection string (for instance 'INFORMATION_SCHEMA').
I can of course change the connection string, replacing the database name, but:
That creates an extra connection pool - one per connection string!
I'm trying to avoid that - having only one connection pool per website.
I was messing around with 'SetDefaultSchema' and other attempts that all fail miserably.
How can I change the database name, the DbContext uses so I only have one connection pool and still each DbContext has its own database to connect to?
The solution is actually quite simple: Use connection interceptor (available from Entity Framework Core 3.0+).
The code below switches the database after the connection has been opened.
Now each DbContext class can use its own database and with only one connection pool in use.
First you create an interceptor class inherited from DbConnectionInterceptor. The constructor takes the database name, you want to switch to, as parameter:
using Microsoft.EntityFrameworkCore.Diagnostics;
using System.Data.Common;
using System.Threading.Tasks;
public class MySqlConnectionInterceptor : DbConnectionInterceptor
{
public MySqlConnectionInterceptor(string databaseName)
{
database = databaseName;
}
readonly string database;
public override void ConnectionOpened(DbConnection connection, ConnectionEndEventData eventData)
{
if (database != null)
{
connection.ChangeDatabase(database); // The 'magic' code
}
base.ConnectionOpened(connection, eventData);
}
public override async Task ConnectionOpenedAsync(DbConnection connection, ConnectionEndEventData eventData, CancellationToken cancellationToken = default)
{
if (database != null)
{
await connection.ChangeDatabaseAsync(database); // The 'magic' code
}
await base.ConnectionOpenedAsync(connection, eventData, cancellationToken);
}
}
Now all you have to is include one line in your DbContext class's OnConfiguring method:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new MySqlConnectionInterceptor("yourDatabase"));
}
Now the connection will switch to 'yourDatabase' database every time, it's opened.
And it will only use one connection pool (total)! That way the number of 'sleeping' connections are kept at a minimum.
This works because Pomelo Entity Framework Core always resets a connection before reusing it from the pool (unless you specifically sets 'Connectionreset=false' - which is bad anyway). It sets the database back to the one in the connection string, which you of course can override again).
Of course you don't have to hard code the database name. If you for instance use a base DbContext class, that your other DbContexts inherits from, you can create a constructor that takes the database name as parameter, like this:
public class BaseDbContext : DbContext
{
public BaseDbContext (string databaseName)
{
database = databaseName;
}
string database;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new MySqlConnectionInterceptor(database));
}
}
The code has been tested in Asp.Net 5+6 and .Net Windows Forms.
Is it possible to change database type at runtime? If yes, how it can be done? I am using EntityFramework 6.
Background about the question:
I have an application that initially does not have database access. A user first has to go through "installation" process and provide information about the database(including database type eg. MySql or MsSql).
I would like to avoid having 2 contexts if possible. If necessary I can provide more details.
You can specify the connection string at runtime using the following...
DbContext has a constructor that can be overloaded with the name of the connection string, or the connection string itself.
public partial class EntityName: DbContext {
public EntityName(): base("name=EntityName") {}
public EntityName(string connectionString): base(connectionString) {}
}
var connString = "PopulateConnString";
Using (var ctx = new EntityName(EntityConnectionStringBuilder)
{
// Do stuff
}
I am trying to use flyway to create and manage a MySQL database. Here is the code i have got so far.
FlywayMigration.java : Class that applys the migration
public class FlywayMigration
{
public FlywayMigration(DatabaseConfiguration configuration, Flyway flyway)
{
flyway.setDataSource(configuration.getDataSource());
flyway.migrate();
}
public static void main(String[] args)
{
new FlywayMigration(new DatabaseConfiguration("database.properties"), new Flyway());
}
}
DatabaseConfiguration.java : Configuration class, this class will configure the datasource to be applyed to the Flyway.setDataSource method
public class DatabaseConfiguration
{
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
private PropertiesUtil prop = null;
public DatabaseConfiguration(String file)
{
prop = new PropertiesUtil(file);
}
public String getDataSourceClass()
{
return prop.getProperty("mysql.data.source.class");
}
public String getURL ()
{
return prop.getProperty("mysql.url");
}
public String getHostName()
{
return prop.getProperty("mysql.host.name");
}
public String getDatabaseName()
{
return prop.getProperty("mysql.database.name");
}
public DataSource getDataSource()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setURL(getURL());
dataSource.setUser(prop.getProperty("mysql.user.name"));
dataSource.setPassword(null);
return dataSource;
}
}
database.properties is the file where i store the database information, password can be null
mysql.data.source.class=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/vmrDB
mysql.host.name=localhost
mysql.database.name=vmrDB
mysql.user.name=root
And i get the folowing error in my trace
Exception in thread "main" org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
at org.flywaydb.core.internal.util.jdbc.JdbcUtils.openConnection(JdbcUtils.java:56)
at org.flywaydb.core.Flyway.execute(Flyway.java:1144)
at org.flywaydb.core.Flyway.migrate(Flyway.java:811)
at com.bt.sitb.vmr.migration.FlywayMigration.<init>(FlywayMigration.java:10)
at com.bt.sitb.vmr.migration.FlywayMigration.main(FlywayMigration.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Can someone please tell me why the DataSource from MySQL is not connecting?
It looks like Flyway cannot connect to the database.
One reason for this is that the database in the database URL does not exist.
Question: does your database schema exist?
If your answer is no, then:
connect to jdbc:mysql://localhost:3306/mysql
also specify the schema to use for migration with flyway.setSchemas(configuration.getDatabaseName())
you also need flyway.init() before you can initialize migration of your database.
Ran into this same issue. Apparently, the problem was with my .properties file. The jar was using the one packaged with it and not the external one. So I moved my external properties file out of the resources folder and into the root directory of the jar and problem solved!
Hope this helps someone.
I had this same issue when working on a Java application in Debian 10 using Tomcat Application server.
I defined the connection strings for the database in the context.xml file, however, when I start out the application and try to log into the application, I get the error:
Exception in thread "main" org.flywaydb.core.api.FlywayException: Unable to obtain Jdbc connection from DataSource
at org.flywaydb.core.internal.util.jdbc.JdbcUtils.openConnection(JdbcUtils.java:56)
at org.flywaydb.core.Flyway.execute(Flyway.java:1144)
Here's what I figured out:
I finally realized that the application was using internally defined database connection strings that were packaged with it. The internally defined database connection strings were different from my own database connection strings defined in the context.xml file.
The solution for me was to either modify the internally defined database connection strings that were packaged with the application or use the same internally defined database connection strings that were packaged with application in my context.xml file.
That's all.
I hope this helps.
I have an issue which I could not find answer for across the web.
I am using CodeFirst EF 4.3.1 Migrations with MySQL.
My MySQL provider is Devart.
After running Add-Migration against an existing database, I got the following code:
public partial class ChangeSet_1231 : DbMigration
{
public override void Up()
{
RenameColumn(table: "RW_TTaskInstanceProperties", name: "TaskInstance_TaskInstanceId", newName: "TaskInstanceId");
}
public override void Down()
{
RenameColumn(table: "RW_TTaskInstanceProperties", name: "TaskInstanceId", newName: "TaskInstance_TaskInstanceId");
}
}
Running Update-Database results in the following error:
PM> Update-Database -verbose –startupprojectname "RTDataAccess"
Using NuGet project 'RTDataAccess'.
Target database is: 'rsruntime' (DataSource: localhost, Provider: Devart.Data.MySql, Origin: Explicit).
Applying explicit migrations: [201205311312361_ChangeSet_1231].
Applying explicit migration: 201205311312361_ChangeSet_1231.
ALTER TABLE RW_TTaskInstanceProperties RENAME COLUMN TaskInstance_TaskInstanceId TO TaskInstanceId
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'COLUMN TaskInstance_TaskInstanceId TO TaskInstanceId' at line 2
From looking at the error details I see that the RenameColumn is translated to a MsSql command, rather than MySql command, so no wonder it reports about a syntax error.
Any ideas how to solve it?
I know I can use Update-Database -script, then edit the script to fit MySql and run it, but I prefer to make the Update-Database command work...
Thanks.
In response to Ladislav's question:
Yes, I registered the Devart's SQL generator for MySQL Migrations.
My Configuration class looks like that:
using Devart.Data.MySql.Entity.Configuration;
using Devart.Data.MySql.Entity.Migrations;
internal sealed class Configuration : DbMigrationsConfiguration<RTDataAccess.RTContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
MySqlEntityProviderConfig.Instance.Workarounds.IgnoreSchemaName = true;
var connectionInfo = MySqlConnectionInfo.CreateConnection("Server=xxxx;Port=yyyy;Database=rsruntime;Uid=zzzz;Pwd=wwww;charset=utf8;");
this.TargetDatabase = connectionInfo;
this.SetSqlGenerator(connectionInfo.GetInvariantName(), new MySqlEntityMigrationSqlGenerator());
}
protected override void Seed(RTDataAccess.RTContext context)
{
}
}
The issue was fixed by Devart.
Details at the following links:
http://forums.devart.com/viewtopic.php?f=2&t=24250
http://www.devart.com/dotconnect/mysql/download.html