简体   繁体   English

实体框架+ MySql + Guid错误

[英]Entity Framework + MySql + Guid error

I am using Entity Framework with MySql. 我在MySql中使用实体框架。

I have problems inserting items in Database using Guid properties. 我在使用Guid属性在数据库中插入项目时遇到问题。

The error i get is: Incorrect string value: '\\x9D?Z\\xC2\\x1C\\xB2...' for column 'Id' at row 1 我得到的错误是: 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. 如果我将属性Id从Guid更改为string ,则工作正常。

The Collation of the table is set to utf8 - default collation . 该表的排序规则设置为utf8 - default collation I have changed it to uft8mb4 - default collation with no effect at all. 我将其更改为uft8mb4 - default collation ,完全没有效果。

The Id property Datatype is VARCHAR(64) PK NN UQ Id属性数据类型为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 这是web.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>
  <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: 我为此使用的软件包(Entity Framework MySql提供程序)是:

<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属性更改为字符串的情况下解决此问题?

GUID is not supported directly in MySql. GUID是不能在MySQL中直接支持。 The right structure to store it is BINARY(16) (you can store the GUID using Guid.ToByteArray). 存储它的股权结构为BINARY(16)(您可以存储使用Guid.ToByteArray的GUID)。 If you want to keep a varchar (I've never used binary to store Ids) you could use 如果您想保留varchar(我从未使用过二进制文件来存储ID),则可以使用

menuItem.Id = String.Format("{0:N}", Guid.NewGuid());

Use CHAR(36) instead of VARCHAR(64). 使用CHAR(36)代替VARCHAR(64)。 EF will then auto map it correctly. EF然后将自动正确映射它。 The same goes for Dapper by the way. 顺便说一句,Dapper也是如此。 I've used both and experimented with BINARY(16) and various VARCHAR() combinations, but CHAR(36) has always worked best with an ORM. 我使用了这两种方法,并尝试使用BINARY(16)和各种VARCHAR()组合,但是CHAR(36)始终与ORM一起使用效果最佳。 Also with BINARY(16) you lose the human readability, which can make debugging difficult. 同样,使用BINARY(16)也会失去人类的可读性,这会使调试变得困难。 I don't know why the MySQL docs recommend VARCHAR(64); 我不知道为什么MySQL文档推荐VARCHAR(64); it's overkill, and uniqueidentifiers are always exactly 36 bytes long, so the var byte is a waste of space. 这是过大的,并且uniqueidentifiers总是正好是36个字节长,所以var字节是浪费空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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