Possibility of using MySQL (or MariaDB) with .Net Core opens an opportunity to use open-source & free database. Moreover, one can take advantage of .Net Core or .Net 5 being cross-platform by bypassing all Microsoft's paid services! Yes, Linux hosting with one of the open-source & free database.
MySQL is technically an open-source database. However, under Oracle, MySQL now has proprietary, closed-source modules. MariaDB, being a MySQL fork, is a good alternative. MariaDB 5.5 offers all of the MySQL 5.5 features1.
In this post, I will show how we can use Entity Framework 5.0 Code First approach to create tables in a MySQL database.
The advantage of using .Net Core again is use of light-weight Visual Studio Code (perhaps one of the best open-source free code editor) with millions of plugins. Great for Linux as Visual Studio is available only for Windows and Mac. I will be using Visual Studio 2019 Community Edition (free) and MySQL 5.7.
We will be using dotnet new command to scaffold builtin template. It can also be done using GUI in Visual Studio.
dotnet new --list
. It shows a list of available templates.D:\DotNetCoreMySQL>dotnet new webapi --framework netcoreapp3.1
. Check here for more template version.This post assumes all the dependencies are installed. .NET Core SDK or Runtime (at least 3.1) (can check installed version using
dotnet --version
), MySQL and Visual Studio or Visual Studio Code (prepare to write more code).
Go to the project folder, right-click PROJECT_NAME.csproj file, and choose 'Open With Visual Studio'
Again, we can install package from Nuget using Visual Studio GUI. However, it's handy to do using CLI in Package Manager Console.
Tips: Open nuget.org so that we can copy CLI from there
dotnet ef
. If you don't see text EF with Unicorn followed by options then we need to install it on command prompt by dotnet tool install --global dotnet-ef --version 5.0.1
We will be using Pomelo provider over MySql.Data.EntityFrameworkCore. The latter one is official MySQL provider, however, I did not have a good experience with it, so my choice is Pomelo.
I am not going to show guidelines regarding creating a database and a user in MySQL. MySQL Workbench cannot be compared with SQL Server Management Studio but quite easy to use.
By default, EF Core will pluralize the generated table name. For example, User will be mapped as Users in the database. To have singularize name, decorate class with the attribute
[Table("User")]
[Table("User")]
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
[Required]
[MaxLength(250)]
public string Address { get; set; }
[Required]
[MaxLength(50)]
public string Country { get; set; }
[MaxLength(15)]
public int Mobile { get; set; }
}
Now, DBContext (database context class) is the main class that coordinates Entity Framework functionality for a given data model. In other words, DBContext looks the models and generates corresponding database tables.
It's good idea to have database related operations in a separate project. But for the sake of simplicity, I am doing on the same project. This approach is not recommended.
public DbSet<User> Users { get; set; }
.The DbContext derived DotNetCoreMySQLContext looks like this:
public class DotNetCoreMySQLContext : DbContext
{
public DotNetCoreMySQLContext(DbContextOptions<DotNetCoreMySQLContext> options) : base(options) {}
public DbSet<User> User { get; set; }
}
appsettings.json
"AllowedHosts": "*",
"ConnectionStrings": {
"DotNetCoreMySQLAppConnection": "server=localhost; port=3306; database=mysqldotnet; user=mysqldotnetuser; password=Pa55w0rd!; Persist Security Info=false; Connect Timeout=300"
}
It's always a bad idea to store password in appsettings.json file. Even if we are pushing in our private repository. This can be avoided by using user secrets. Again, for the sake of simplicity, I am using plain password. However, user secrets is a good topic for a blog itself!
ConfigureServices method from startup.cs
public void ConfigureServices(IServiceCollection services)
{
string dbConnectionString = Configuration.GetConnectionString("DotNetCoreMySQLAppConnection");
services.AddDbContext<DotNetCoreMySQLContext>(opt => opt.UseMySql(dbConnectionString, ServerVersion.AutoDetect(dbConnectionString)));
services.AddControllers();
}
This line services.AddDbContext<DotNetCoreMySQLContext>(opt => opt.UseMySql(dbConnectionString, ServerVersion.AutoDetect(dbConnectionString)))
tells the app to use MySQL provider and our context class with the connection string from appsettings.json.
Now, we have setup everything to use Code-First approach to create tables in the database. Entity Framework keep tracks of all models through migrations. Every time, we update or create model, we need to do so my making a unique migration. These migrations becomes a sort of record and they can be used to roll-back in the event of an error.
PM> dotnet ef migrations add FirstMigration
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PM>
EF creates a folder called Migrations at the root of the project to store all migrations. 2. Apply changes to the database by typing command given below. Remember, MySQL server must be running at this time.
PM> dotnet ef database update
Build started...
Build succeeded.
Done.
Open MySQL Workbench (or your SQL editor) and confirm the creation of the table.
Change the Target Framework by right-clicking on the Project name. On Application tab choose .Net 5.0 from the Target Framework dropdown. The can also be done by opening PROJECTNAME.csproj_ file in text editor and changing
<TargetFramework>net5.0</TargetFramework>
. NOTE: .NET 5 SDK or runtime must be installed.
dotnet ef migrations add NewModel
dotnet ef database udpate
Refresh the database in MySQL to confirm the new table is created.