MySQL 5.5 + .NET Connector + Entity Framework + Migrations = FormatException

时间:2012-09-12 01:38:31

标签: mysql ef-code-first entity-framework-5

我试图为我的问题找到一个解决方案,但直到现在我的努力都是徒劳的。 : - (

我使用Visual Studio 2010,.NET Framework 4,C#,Entity Framework 5.0,MySQL 5.5及其相应的.NET连接器(6.5.4版)创建了一个Web项目。我正在使用代码优先实现实体和O / R映射。

我遇到的问题是我无法执行看似简单的迁移。这是我的实体类:

public class Usuario
{
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string NomeCompleto { get; set; }

    [Required]
    [StringLength(100)]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [Required]
    [StringLength(30)]
    public string Login { get; set; }

    [Required]
    [StringLength(64)]
    public string Senha { get; set; }

    [Required]
    public bool Ativo { get; set; }

    //[Timestamp]
    [ConcurrencyCheck]
    public int Versao { get; set; }
}

public class Perfil
{
    public int Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Nome { get; set; }

    [StringLength(100)]
    public string Descricao { get; set; }

    //[Timestamp]
    [ConcurrencyCheck]
    public int Versao { get; set; }

    public virtual ICollection<Usuario> Usuarios { get; set; }
    public virtual ICollection<Permissao> Permissoes { get; set; }
}

public class Permissao
{
    public int Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Nome { get; set; }

    [StringLength(100)]
    public string Descricao { get; set; }

    //[Timestamp]
    [ConcurrencyCheck]
    public int Versao { get; set; }

    public virtual ICollection<Perfil> Perfis { get; set; }
}

Add-Migration Acesso生成的代码(仅Up()方法):

public partial class Acesso : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.Usuario",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    NomeCompleto = c.String(nullable: false, storeType: "mediumtext"),
                    Email = c.String(nullable: false, storeType: "mediumtext"),
                    Login = c.String(nullable: false, storeType: "mediumtext"),
                    Senha = c.String(nullable: false, storeType: "mediumtext"),
                    Ativo = c.Boolean(nullable: false),
                    Versao = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.Perfil",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Nome = c.String(nullable: false, storeType: "mediumtext"),
                    Descricao = c.String(storeType: "mediumtext"),
                    Versao = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.Permissao",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Nome = c.String(nullable: false, storeType: "mediumtext"),
                    Descricao = c.String(storeType: "mediumtext"),
                    Versao = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.PerfilPermissao",
            c => new
                {
                    PerfilId = c.Int(nullable: false),
                    PermissaoId = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.PerfilId, t.PermissaoId })
            .ForeignKey("dbo.Perfil", t => t.PerfilId, cascadeDelete: true)
            .ForeignKey("dbo.Permissao", t => t.PermissaoId, cascadeDelete: true)
            .Index(t => t.PerfilId)
            .Index(t => t.PermissaoId);

        CreateTable(
            "dbo.UsuarioPerfil",
            c => new
                {
                    UsuarioId = c.Int(nullable: false),
                    PerfilId = c.Int(nullable: false),
                })
            .PrimaryKey(t => new { t.UsuarioId, t.PerfilId })
            .ForeignKey("dbo.Usuario", t => t.UsuarioId, cascadeDelete: true)
            .ForeignKey("dbo.Perfil", t => t.PerfilId, cascadeDelete: true)
            .Index(t => t.UsuarioId)
            .Index(t => t.PerfilId);

    }
}

首先,我必须从

更改名为Versao(版本)的属性
[Timestamp]
public byte[] Versao { get; set; }

[ConcurrencyCheck]
public int Versao { get; set; }

因为在更改之前发生了错误(关于类型rowversion的某些内容未使用命名空间或别名限定)。在此更改之后,我能够生成迁移,但Update-Database命令失败,并在控制台中显示以下错误:

System.FormatException: Cadeia de entrada não estava em um formato incorreto.
    em System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)

(输入字符串的格式不正确。)

我尝试使用MySQL版本5.5和5.1;连接器的6.5.4,6.4.5和6.3.9版本无法解决问题。

是否可以使用MySQL,实体框架和代码第一种方法?如果没有,切换到ODBC连接器而不是.NET连接器有什么后果?

提前致谢并抱歉这个大问题。

6 个答案:

答案 0 :(得分:21)

我是MySQL数据连接器v.6.6.4的created a fork,它支持最新版本的Entity Framework(v.5)。

要使用它,您可以download the binaries,它们是MySql.DataMySql.Data.Entity的替换程序集。还要确保您的项目依赖于EF5而不是4.3。

第一次Enable-Migrations后,修改您的Configuration类'构造函数以包含该行:

SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());

此时,您应该可以毫无问题地运行Add-MigrationUpdate-Database

我叉子的主要变化如下:

  • 二进制文件依赖于EF5而不是EF4.3。

  • EF5将dbo.预先添加到MySQL无法处理的所有表名中。因此,我的版本破解了SQL迁移生成器,从表名中删除dbo.前缀。这一切都假设您没有通过实体类上的TableAttribute覆盖架构。

  • 它删除了Jimi在答案中提到的CreatedOn的用法。

答案 1 :(得分:3)

您还应该尝试.NET Connector 6.6,因为它是第一个声称支持EF 4.3(第一个带迁移的版本)的版本。如果它没有帮助,您应该尝试dotConnect for MySql(至少试用)来查找问题是在.NET Connector还是在EF中。 ODBC连接器不适用于EF。

答案 2 :(得分:2)

我不认为.Net Connector 6.6支持代码迁移。我已经尝试过,当你运行'Update-Database'时你会得到错误 找不到提供者'MySql.Data.MySqlClient'的MigrationSqlGenerator。使用目标迁移配置类中的SetSqlGenerator方法注册其他SQL生成器。 dotConnect for MySql可能会起作用,因为他们已经添加了迁移支持

答案 3 :(得分:2)

有一些有用的指南如何使用EF + Connector / Net + EFMigrations ..我认为如果你检查它会有所帮助。最新版本的Connector / Net(6.6.4)取决于EF 4.3.1支持EF 5的Connector / Net版本仍处于代码阶段。

HowTo using EF Migrations and Connector/Net

Upgrading to Code Based Migrations EF 4.3.1 with Connector/Net 6.6

希望这有帮助!

答案 4 :(得分:0)

使用EF CTP5(a.k.a版本4.4.0)的事情是不推荐使用CreatedOn方法(用于在数据库中创建相关表),而Connector / Net 6.6正在尝试迁移该表导致异常。

答案 5 :(得分:0)

我得到了下面提到的错误

找不到提供者'MySql.Data.MySqlClient'的MigrationSqlGenerator。使用目标迁移配置类中的SetSqlGenerator方法注册其他SQL生成器。

并通过此声明得到修复

SetSqlGenerator("MySql.Data.MySqlClient", new ySql.Data.Entity.MySqlMigrationSqlGenerator());

T enter image description here需要在Configuration构造函数下设置它。