Entity framework 5.0 code-first with MySQL in WPF - mysql

This walkthrough works great with SQL Express:
http://msdn.microsoft.com/en-us/library/gg197522(v=VS.103).aspx
I would like it to work with MySQL. I've done some research but none of the techniques I've found has been able to do it for me. Ideally I would like to do something like this:
<entityFramework>
<defaultConnectionFactory type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" />
</entityFramework>
This doesn't work (I have MySQL Connector Net 6.5.4 installed & MySql.Data referenced). I've tried deriving from IDbConnection factory as shown in this class here:
http://www.vworker.com/RentACoder/misc/BidRequests/ShowBidRequest.asp?lngBidRequestId=1563829
and then using:
<entityFramework>
<defaultConnectionFactory type="SchoolModel.MySqlConnectionFactory, SchoolModel" />
but that doesn't work either. Can anybody please give me some pointers as to how to get this to work?
Many thanks.

To use Connector 6.5.4 with code-first EF5 on VS2012 you need:
Install MySql Connector 6.5.4 msi
Open VS2012 x86 Command Prompt as Admin and execute:
gacutil /i "C:\Program Files (x86)\MySQL\Connector NET 6.5.4\Assemblies\v4.0\mysql.data.dll"
gacutil /i "C:\Program Files (x86)\MySQL\Connector NET 6.5.4\Assemblies\v4.0\mysql.data.entity.dll"
Add in your project's App.config this code to <configuration> section:
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add
name="MySQL Data Provider"
invariant="MySql.Data.MySqlClient"
description=".Net Framework Data Provider for MySQL"
type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data,
Version=6.5.4.0, Culture=neutral,
PublicKeyToken=c5687fc88969c44d"
/>
</DbProviderFactories>
</system.data>
Now add references to MySql.Data and MySql.Data.Entity to your solution and some code like this (I create MySqlConnection, then pass it to constructor of MyDbContext)
public class MyDbContext : DbContext
{
public MyDbContext(DbConnection connection) : base(connection, true) { } ​
public DbSet<Product> Products { get; set; }
}
[Table("sund_jshopping_products")]
public class Product
{
[Key]
[Column("product_id")]
public int Id { get; set; }
[Column("product_ean")]
public string Ean { get; set; }
[Column("product_manufacturer_id")]
public int OperatorId { get; set; }
[Column("months_status")]
public string MonthsStatus { get; set; }
[Column("extra_field_5")]
public string SideId { get; set; }
}

Connector 6.5.4 does not support code-first with EF 5. Actually it does not support code first.
You can try using dot net connector (at least the trial version).

Did you set the Datasource to MySQL while setting up your db connection. Also, click and make sure "Test Connection" succeeds before trying a connection directly from the code.

Related

troubles with vb net, mysql and entity framework 6 sbyte type

I've defined a project in visual studio 2015, I've used ADO NET Code first to connect with a mysql database (mysql connector 6.9.9), and now, having the model, I'm trying to use entity framework 6.
I've installed from nuget 'mysql entity framework 6.9.9' in my project, but when I try to connect with the model, next message is shown:
SBYTE THERE IS NO STORE TYPE Corresponding to the conceptual side type
'SBYTE' of primitive type 'SBYTE'
.Net framework 4.5.2
Any suggest??
Thanks!!
SByte is not a data type supported by the providers (at least is not supported by SQL Server, SQL Server CE, Microsoft Access, MySQL).
If you Really Want a class with an SByte, the best way is to use a [private] backing and expose the SByte property.
This is the model for a private backing field.
public class Info
{
public int Id { get; set; }
[MaxLength(50)]
public string Description { get; set; }
public sbyte SByte
{
get
{
return (sbyte) SByteBackingField;
}
set
{
SByteBackingField = value;
}
}
private int SByteBackingField { get; set; }
public class InfoMap : EntityTypeConfiguration<Info>
{
public InfoMap()
{
ToTable("Infoes69");
Property(_ => _.SByteBackingField).HasColumnName("SByte");
Ignore(_ => _.SByte);
}
}
}
and in context you need to add the configuration
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new Info.InfoMap());
}
The issue is that you can't use SByte property in queries.
I experienced this when using MySQL because EntityFramework defaults to using SQL Server - which does not have this data type.
The solution (for me) had 2 parts, either of which caused the same error:
Go into Web.Config, and set the correct provider for entity framework
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.10.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</providers>
Make sure that the connection string was set properly.
YMMV!

MySQL and Entity Framework issues

I am attempting to use EF6 to connect to a MySql DB. I've looked at NUMEROUS examples and they all look different. I see so many different ways and they are not like connecting to Oracle, which I have experience with.
public string GetWebinarList()
{
string str = "";
string connectionString = "server=127.0.0.1;port=3306;UserId=user;database=db;password=pwd;CharSet=utf8;Persist Security Info=True;";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
using (webinarListDbContext context = new webinarListDbContext())
{
var list = context.WebinarLists.ToString();
str = list;
}
connection.Close();
}
return str;
}
The above actually looks more like connecting through ADO.DB than EF6.
The Context definition:
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class webinarListDbContext : DbContext
{
public webinarListDbContext() : this("MonkeyFist") { }
public webinarListDbContext(string connStringName) : base(connStringName) { }
static webinarListDbContext()
{
// static constructors are guaranteed to only fire once per application.
// I do this here instead of App_Start so I can avoid including EF
// in my MVC project (I use UnitOfWork/Repository pattern instead)
DbConfiguration.SetConfiguration(new MySql.Data.Entity.MySqlEFConfiguration());
}
public DbSet<WebinarList> WebinarLists { get; set; }
}
Web.Config:
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
<connectionStrings>
<add name="MonkeyFist" providerName="MySql.Data.MySqlClient" connectionString="server=127.0.0.1;port=3306;UserId=user;database=db;password=pwd;CharSet=utf8;Persist Security Info=True;"/>
</connectionStrings>
</system.data>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</providers>
</entityFramework>
But this is what I see when I inspect the context object:
What the heck is it using a SQLClient connection for vs. a MySQLClient? And Why would MonkeyFist be set as the Database? How would I connect EF6 to MySQL?
The reason you are seeing this behaviour is that you are not actually passing your connection object to your context. Instead you are passing the string "MonkeyFist", which the context assumes is the name of a db. Since it cannot find this db in your config file, it creates a local db with the same name.
See here: https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.113).aspx
If the parameterless DbContext constructor is called from a derived context, then the name of the derived context is used to find a connection string in the app.config or web.config file. If no connection string is found, then the name is passed to the DefaultConnectionFactory registered on the Database class. The connection factory then uses the context name as the database name in a default connection string. (This default connection string points to .\SQLEXPRESS on the local machine unless a different DefaultConnectionFactory is registered.) Instead of using the derived context name, the connection/database name can also be specified explicitly by passing the name to one of the DbContext constructors that takes a string.
Pass your connection object to your context.

Windows Service: EF + MySql without app.config

At the moment I'm writing a windows service.
I'm already using EntityFramework with MSSQL database which is working perfectly. Now I have to use MySql parallely. But I can't manage to get it running ... I would like to avoid using the app.config and configure EntityFramework via the constructor of my class derived from DbContext.
I have a SqlContext class:
public class SqlContext : DbContext
{
public IDbSet<ServiceauftragSource> ServiceauftragSource { get; set; }
public SqlContext(string connectionString)
: base(connectionString)
{
}
public SqlContext(DbConnection connection)
: base(connection, true)
{
this.Configuration.LazyLoadingEnabled = true;
}
}
In the constructor of my UnitOfWork I try to create my SqlContext:
public SqlUnitOfWork()
{
const string connStr = "server=127.0.0.1;uid=myuser;pwd=mypw;database=mydb;";
MySqlConnection conn = new MySqlConnection(connectionString);
this.Context = new SqlContext(conn);
}
This didn't work. I get the following message when trying to access the database:
Unable to determine the DbProviderFactory type for connection of type 'MySql.Data.MySqlClient.MySqlConnection'. Make sure that the ADO.NET provider is installed or registered in the application config.
Neither did:
public SqlUnitOfWork()
{
this.SetConnectionString();
this.Context = new SqlContext(connectionString);
}
private void SetConnectionString()
{
this.connectionString = "Data Source=" + debugDatabaseServer + ";Initial Catalog=" + debugDatabaseName
+ ";User ID=" + debugDatabaseUsername + ";Password=" + debugDatabasePassword
+ ";Trusted_Connection=False;Persist Security Info=True;";
}
I'm not sure why but I think this is because I haven't told my context its provider (according to other threads on SO it has to be MySql.Data.MySqlClient). But where and how to?
References of the project:
Update
I tried to use my App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MySqlContext" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;
port=3306;database=***;uid=***;password=***"/>
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices,
MySql.Data.Entity.EF6" />
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
When accessing the database I get the following error:
Object reference not set to an instance of an object.
I think this is because my service can't access the app.config after it's being installed. I ensured that app.config is MyService.exe.config after build ...
I've been using MySQL with EF for quite some time pretty flawlessly, what yo need to do is add the following line above your DBContext
[DbConfigurationType(typeof (MySql.Data.Entity.MySqlEFConfiguration))]
so in your case the snippet would look like
[DbConfigurationType(typeof (MySql.Data.Entity.MySqlEFConfiguration))]
public class SqlContext : DbContext
{
public IDbSet<ServiceauftragSource> ServiceauftragSource { get; set; }
public SqlContext(string connectionString)
: base(connectionString)
{
}
public SqlContext(DbConnection connection)
: base(connection, true)
{
this.Configuration.LazyLoadingEnabled = true;
}
}
as for your connection string, i tend to store mine in the web config and then string format for whatever db,server or user i need to create a context for - hope that helps!
NB Im presuming you have your refs to MySQL.data and EF6 as well!

ASP.Net MVC with MySql - unable to find the requested .Net Framework Data Provider

I have installed the MySql Connector 6.6.5 from http://dev.mysql.com/downloads/connector/net/
I have added it as a reference in my asp.net MVC website (please see screenshots below), and changed "Copy local" to true.
However, when I get to the line:var calls = db.Calls.ToList(); I get the error:
Unable to find the requested .Net Framework Data Provider. It may not be installed.
I've included my code below. Can anyone please let me know what I'm missing?
Thanks, Mark
Controller Call.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MySql.Data;
using MySql.Data.Entity;
using MySql.Data.MySqlClient;
using MySql.Web;
using System.Data;
namespace bm.Controllers
{
public class CallController : Controller
{
private CallContext db = new CallContext();
//
// GET: /Calls/
public ActionResult Index()
{
var calls = db.Calls.ToList();
return View(calls);
}
}
}
CallContext.cs
using bm.Models;
using System.Data.Entity;
public class CallContext : DbContext
{
static CallContext()
{
}
public CallContext()
: base("callsConn")
{
}
public DbSet<Call> Calls { get; set; }
}
Web.Config Connection String:
<connectionStrings>
<add name="callsConn" connectionString="Server=xxx;Port=3306;Database=xxxx;Uid=root;Pwd=;" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
References:
Update
I seem to have solved this by adding the following to my web.config:
<system.data>
<DbProviderFactories >
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
Hope it helps someone else.
Mark

ASP.NET MVC 4 EF5 with MySQL

So I've just picked up VS2012 and I want to start an ASP.NET MVC 4 app with EF5.
My host does not have MSSQL so I have to use MySQL.
How do I tell my app that it should use MySQL? (I either want to use the devart MySQL connector or the one from mysql.com)
You need to setup your config with a connection string, DbProviderFactory and a custom DatabaseInitializer for MySql Connector 6.5.4. I have detailed the full step for getting EF5 and MySql to play, including code for the initializers on my blog. If you require ASP.Net membership provider solution it been asked before: ASP.NET Membership/Role providers for MySQL? I will post the solution here also for a complete EF5 MySql solution.
The MySql connector does not currently support EF 5 migration and ASP.NET only supports SimpleMembership (MVC4 default) on MS SQL not MySql. The solution below is for Code First.
The steps are:
Grab EF 5 from NuGet
Grab MySql.Data and MySql.Data.Entity from NuGet (6.5.4) or MySql (6.6.4)
Configure a MySql Data Provider
Configure a MySql Connection String
Create a Custom MySql Database Initializer
Configure the Custom MySql Database Initializer
Configure ASP.NET membership if you require it
DbProvider
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient"/>
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient"
description=".Net Framework Data Provider for MySQL"
type="MySql.Data.MySqlClient.MySqlClientFactory,MySql.Data" />
</DbProviderFactories>
</system.data>
Connection String
<connectionStrings>
<add name="ConnectionStringName"
connectionString="Datasource=hostname;Database=schema_name;uid=username;pwd=Pa$$w0rd;"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
Database Initializer
If you are using MySql connector from NuGet (6.5.4) then a custom initializer is required. Code available at http://brice-lambson.blogspot.se/2012/05/using-entity-framework-code-first-with.html
or at http://www.nsilverbullet.net/2012/11/07/6-steps-to-get-entity-framework-5-working-with-mysql-5-5/
Then add this to configuration
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,
EntityFramework, Version=5.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089" />
</configSections>
<entityFramework>
<contexts>
<context type="Namespace.YourContextName, AssemblyName">
<databaseInitializer
type="Namespace.YourChosenInitializer, AssemblyName">
</databaseInitializer>
</context>
</contexts>
<defaultConnectionFactory
type="MySql.Data.MySqlClient.MySqlClientFactory,MySql.Data" />
</entityFramework>
ASP.NET Membership
<membership defaultProvider="MySqlMembershipProvider">
<providers>
<clear />
<add name="MySqlMembershipProvider"
type="MySql.Web.Security.MySQLMembershipProvider,
MySql.Web, Version=6.5.4.0, PublicKeyToken=c5687fc88969c44d"
autogenerateschema="true"
connectionStringName="*NAME_OF_YOUR_CONN_STRING*"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
applicationName="/" />
</providers>
</membership>
Get the AccountController and Views working:
Delete the MVC 4 AccountController, AccountModels, Account view folder and _LoginPartial shared view
Create a new MVC 3 web application
Copy the MVC 3 AccountController, AccountModels, Account view folder and _LogOnPartial shared view into your MVC 4 application
Replace #Html.Partial(“_LoginPartial”) in the shared _Layout view with #Html.Partial(“_LogOnPartial”)
<add name="ConnectionString" providerName="MySql.Data.MySqlClient" connectionString="Data Source=127.0.0.1; port=3306; Initial Catalog=DbName; uid=root; pwd=*Password*;" />
Install Package:
PM> Install-Package EntityFramework
PM> Update-Package EntityFramework
PM> Install-Package MySql.Data.Entity
Web.config
<connectionStrings>
<add name="DefaultConnection"
providerName="MySql.Data.MySqlClient"
connectionString="Data Source=localhost;port=3306;Initial Catalog=api_db;User Id=root;password=''"/>
</connectionStrings>
Create Model Class
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace LiteRemit.Models
{
[Table("customers")]
public class CustomerModel
{
[Key]
public int CustomerId { get; set; }
public string Name { get; set; }
public string Country { get; set; }
}
}
Create Model Context:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace LiteRemit.Models
{
public class MySqlCon : DbContext
{
//MySql Database connection String
public MySqlCon() : base(nameOrConnectionString: "DefaultConnection") { }
public virtual DbSet<CustomerModel> Customers { get; set; }
}
}
Create Controller Class
using LiteRemit.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace LiteRemit.Controllers
{
public class HomeController : Controller
{
MySqlCon _con;
public HomeController()
{
_con = new MySqlCon();
}
public ActionResult Index()
{
return View(_con.Customers.ToList());
}
}
}
Code add view page:
#using LiteRemit.Models
#model IEnumerable<CustomerModel>
<table border="1">
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.CustomerId)</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>#Html.DisplayFor(modelItem => item.Country)</td>
</tr>
}
</table>