简体   繁体   中英

Entity Framework + MySql + Guid error

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?

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());

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM