This article shows how to use MySQL with ASP.NET Core 1.0 using Entity Framework Core.
Code: https://github.com/damienbod/AspNet5MultipleProject
Thanks to Noah Potash for creating this example and adding his code to this code base.
The Entity Framework MySQL package can be downloaded using the NuGet package SapientGuardian.EntityFrameworkCore.MySql. At present no official provider from MySQL exists for Entity Framework Core which can be used in an ASP.NET Core application.
The SapientGuardian.EntityFrameworkCore.MySql package can be added to the project.json file.
{ "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0", "type": "platform" }, "DomainModel": "*", "SapientGuardian.EntityFrameworkCore.MySql": "7.1.4" }, "frameworks": { "netcoreapp1.0": { "imports": [ "dotnet5.6", "dnxcore50", "portable-net45+win8" ] } } }
An EfCore DbContext can be added like any other context supported by Entity Framework Core.
using System; using System.Linq; using DomainModel.Model; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace DataAccessMySqlProvider { // >dotnet ef migration add testMigration public class DomainModelMySqlContext : DbContext { public DomainModelMySqlContext(DbContextOptions<DomainModelMySqlContext> options) :base(options) { } public DbSet<DataEventRecord> DataEventRecords { get; set; } public DbSet<SourceInfo> SourceInfos { get; set; } protected override void OnModelCreating(ModelBuilder builder) { builder.Entity<DataEventRecord>().HasKey(m => m.DataEventRecordId); builder.Entity<SourceInfo>().HasKey(m => m.SourceInfoId); // shadow properties builder.Entity<DataEventRecord>().Property<DateTime>("UpdatedTimestamp"); builder.Entity<SourceInfo>().Property<DateTime>("UpdatedTimestamp"); base.OnModelCreating(builder); } public override int SaveChanges() { ChangeTracker.DetectChanges(); updateUpdatedProperty<SourceInfo>(); updateUpdatedProperty<DataEventRecord>(); return base.SaveChanges(); } private void updateUpdatedProperty<T>() where T : class { var modifiedSourceInfo = ChangeTracker.Entries<T>() .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); foreach (var entry in modifiedSourceInfo) { entry.Property("UpdatedTimestamp").CurrentValue = DateTime.UtcNow; } } } }
In an ASP.NET Core web application, the DbContext is added to the application in the startup class. In this example, the DbContext is defined in a different class library. The MigrationsAssembly needs to be defined, so that the migrations will work. If the context and the migrations are defined in the same assembly, this is not required.
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile("config.json", optional: true, reloadOnChange: true); Configuration = builder.Build(); } public void ConfigureServices(IServiceCollection services) { var sqlConnectionString = Configuration.GetConnectionString("DataAccessMySqlProvider"); services.AddDbContext<DomainModelMySqlContext>(options => options.UseMySQL( sqlConnectionString, b => b.MigrationsAssembly("AspNet5MultipleProject") ) ); }
The application uses the configuration from the config.json. This file is used to get the MySQL connection string, which is used in the Startup class.
{ "ConnectionStrings": { "DataAccessMySqlProvider": "server=localhost;userid=damienbod;password=1234;database=damienbod;" } } }
MySQL workbench can be used to add the schema ‘damienbod’ to the MySQL database. The user ‘damienbod’ is also required, which must match the defined user in the connection string. If you configure the MySQL database differently, then you need to change the connection string in the config.json file.
Now the database migrations can be created and the database can be updated.
> > dotnet ef migrations add testMySql > > dotnet ef database update >
If successful, the tables are created.
The MySQL provider can be used in a MVC 6 controller using construction injection.
using System.Collections.Generic; using DomainModel; using DomainModel.Model; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; namespace AspNet5MultipleProject.Controllers { [Route("api/[controller]")] public class DataEventRecordsController : Controller { private readonly IDataAccessProvider _dataAccessProvider; public DataEventRecordsController(IDataAccessProvider dataAccessProvider) { _dataAccessProvider = dataAccessProvider; } [HttpGet] public IEnumerable<DataEventRecord> Get() { return _dataAccessProvider.GetDataEventRecords(); } [HttpGet] [Route("SourceInfos")] public IEnumerable<SourceInfo> GetSourceInfos(bool withChildren) { return _dataAccessProvider.GetSourceInfos(withChildren); } [HttpGet("{id}")] public DataEventRecord Get(long id) { return _dataAccessProvider.GetDataEventRecord(id); } [HttpPost] public void Post([FromBody]DataEventRecord value) { _dataAccessProvider.AddDataEventRecord(value); } [HttpPut("{id}")] public void Put(long id, [FromBody]DataEventRecord value) { _dataAccessProvider.UpdateDataEventRecord(id, value); } [HttpDelete("{id}")] public void Delete(long id) { _dataAccessProvider.DeleteDataEventRecord(id); } } }
The controller api can be called using Fiddler:
POST http://localhost:5000/api/dataeventrecords HTTP/1.1 User-Agent: Fiddler Host: localhost:5000 Content-Length: 135 Content-Type: application/json; { "DataEventRecordId":3, "Name":"Funny data", "Description":"yes", "Timestamp":"2015-12-27T08:31:35Z", "SourceInfo": { "SourceInfoId":0, "Name":"Beauty", "Description":"second Source", "Timestamp":"2015-12-23T08:31:35+01:00", "DataEventRecords":[] }, "SourceInfoId":0 }
The data is added to the database as required.
Links:
https://github.com/SapientGuardian/SapientGuardian.EntityFrameworkCore.MySql
http://dev.mysql.com/downloads/mysql/
Experiments with Entity Framework Core and ASP.NET Core 1.0 MVC
https://docs.efproject.net/en/latest/miscellaneous/connection-strings.html
