Reputation: 11721
I am using Entity Framework with MySql.
I have problems inserting items in Database using Guid properties.
The error i get is: Incorrect string value: '\x9D?Z\xC2\x1C\xB2...' for column 'Id' at row 1
If i change the property Id from Guid
to string
, it works fine.
The Collation of the table is set to utf8 - default collation
. I have changed it to uft8mb4 - default collation
with no effect at all.
The Id
property Datatype is VARCHAR(64)
PK NN UQ
Here is the simplified code
public class AppFormAppUnitOfWork : DbContext
{
public DbSet<MenuItem> MenuItems { get; set; }
}
static void MySqlGuid(AppFormAppUnitOfWork unitOfWork)
{
MenuItem menuItem = new MenuItem();
menuItem.Id = Guid.NewGuid();
menuItem.MenuItem_Name = "Hello World";
unitOfWork.MenuItems.Add(menuItem);
using (var trans = new TransactionScope())
{
// throws
// Incorrect string value: '\x9D?Z\xC2\x1C\xB2...' for column 'Id' at row 1
unitOfWork.SaveChanges();
trans.Complete();
}
}
static void MySqlString(AppFormAppUnitOfWork unitOfWork)
{
MenuItem menuItem = new MenuItem();
menuItem.Id = Guid.NewGuid().ToString();
menuItem.MenuItem_Name = "Hello World";
unitOfWork.MenuItems.Add(menuItem);
using (var trans = new TransactionScope())
{
// works ok
unitOfWork.SaveChanges();
trans.Complete();
}
}
Here are the web.config settings
<?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>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings>
<add name="AppFormAppUnitOfWork" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=appformapp;uid=root;password=microsoft;Old Guids=true;Charset=utf8;" />
</connectionStrings>
<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.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d">
</provider>
</providers>
</entityFramework>
</configuration>
The packages (Entity Framework MySql provider) i am using for this are:
<packages>
<package id="EntityFramework" version="6.0.0" targetFramework="net45" />
<package id="MySql.Data" version="6.9.6" targetFramework="net45" />
<package id="MySql.Data.Entity" version="6.9.6" targetFramework="net45" />
</packages>
How can i fix this problem without changing all the Guid properties to string?
Upvotes: 1
Views: 2746
Reputation: 92
Use CHAR(36) instead of VARCHAR(64). EF will then auto map it correctly. The same goes for Dapper by the way. I've used both and experimented with BINARY(16) and various VARCHAR() combinations, but CHAR(36) has always worked best with an ORM. Also with BINARY(16) you lose the human readability, which can make debugging difficult. I don't know why the MySQL docs recommend VARCHAR(64); it's overkill, and uniqueidentifiers are always exactly 36 bytes long, so the var byte is a waste of space.
Upvotes: 0
Reputation: 6491
GUID is not supported directly in MySql. The right structure to store it is BINARY(16) (you can store the GUID using Guid.ToByteArray). If you want to keep a varchar (I've never used binary to store Ids) you could use
menuItem.Id = String.Format("{0:N}", Guid.NewGuid());
Upvotes: 1