EF6代码优先+ MySql迁移:不支持类型nvarchar(max)

时间:2014-06-30 18:52:57

标签: mysql entity-framework ef-migrations

我正在尝试首先使用EF6代码+ MySql进行迁移,但我在add-migration期间遇到此错误:

The underlying provider does not support the type 'nvarchar(max)'

因此,即使我在配置中更改了默认连接工厂,EF似乎也在尝试将SQLServer类型用于MySql。

我可以使用相同的错误消息找到很多问题但是它们似乎都不是最新的或建议我还没有尝试过的东西。以下是我在MySql的DAL dll中启用迁移的步骤,是否有人可以提示?

(1)添加NuGet

  • MySql.ConnectorNET.Data
  • MySql.ConnectorNET.Entity

(2)在App.config文件中为MySql添加连接字符串,如:

(connectionStrings)
(add name="MySqlConn" 
     connectionString="Data Source=127.0.0.1;Port=3306;Database=dummy;User id=***;Password=***;charset=utf8" 
     providerName="MySql.Data.MySqlClient" /)
(/connectionStrings)

(3)另外,确保NuGet按照规定修改配置(在我的情况下为App.config):

  • 替换默认连接工厂:

    (defaultconnectionfactory type =“MySql.Data.Entity.MySqlConnectionFactory,MySql.Data.Entity.EF6”/)

  • 添加MySql提供程序:

    (provider invariantname =“MySql.Data.MySqlClient”             type =“MySql.Data.MySqlClient.MySqlProviderServices,MySql.Data.Entity.EF6,Version = 6.8.3.0,Culture = neutral,PublicKeyToken = c5687fc88969c44d”/)

  • 将提供程序添加到system.data:

    (system.data)     (dbproviderfactories)         (删除name =“MySQL Data Provider”invariant =“MySql.Data.MySqlClient”/)         (添加name =“MySQL数据提供者”                 不变= “MySql.Data.MySqlClient”                 description =“。用于MySQL的Net Framework数据提供程序”                 type =“MySql.Data.MySqlClient.MySqlClientFactory,MySql.Data,Version = 6.8.3.0,Culture = neutral,PublicKeyToken = c5687fc88969c44d”/)     (/ dbproviderfactories) (/system.data)

(4)按照http://dev.mysql.com/doc/connector-net/en/connector-net-entityframework60.html的建议手动添加代码配置类型属性(我不想触摸我的数据上下文代码,因为它必须保持通用):

(entityframework codeconfigurationtype="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6")

我的POCO对象中的一些字符串属性没有最大长度,因为它们必须是nvarchar(max),即MySql中的text。然而,我得到了上面引用的错误,这个堆栈跟踪:

System.ArgumentException: The underlying provider does not support the type 'nvarchar(max)'.
   at MySql.Data.MySqlClient.MySqlProviderManifest.GetEdmType(TypeUsage storeType)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.BuildColumnModel(EdmProperty property, ModelMetadata modelMetadata, IDictionary`2 annotations)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.BuildAlterColumnOperation(String table, EdmProperty targetProperty, ModelMetadata targetModelMetadata, EdmProperty sourceProperty, ModelMetadata sourceModelMetadata)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.(FindAlteredColumns)b__24b(()f__AnonymousType2c`2 ()h__TransparentIdentifier243)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(ModelMetadata source, ModelMetadata target, Lazy`1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy`1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion)
   at System.Data.Entity.Migrations.DbMigrator.Scaffold(String migrationName, String namespace, Boolean ignoreChanges)
   at System.Data.Entity.Migrations.Design.MigrationScaffolder.Scaffold(String migrationName, Boolean ignoreChanges)
   at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Scaffold(MigrationScaffolder scaffolder)
   at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Scaffold(String migrationName, String language, String rootNamespace, Boolean ignoreChanges)
   at System.Data.Entity.Migrations.AddMigrationCommand.Execute(String name, Boolean force, Boolean ignoreChanges)
   at System.Data.Entity.Migrations.AddMigrationCommand.()c__DisplayClass2.(.ctor)b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
The underlying provider does not support the type 'nvarchar(max)'.

任何提示?

3 个答案:

答案 0 :(得分:2)

我整晚都在努力解决同样的错误。修复是违反直觉的,但到目前为止一直很好......似乎问题与使用LocalDB(SQL Server)设置的旧迁移有关,但即使删除旧的迁移也没有效果。我还花费了大量不必要的时间来摆弄我的Web.config,数据库环境等等...我建议在敲打墙头之前尝试以下方法......

  1. 删除迁移文件夹
  2. 尝试启用迁移并添加初始迁移(在PM类型中为“enable-migrations”,然后是“add-migration init”)
  3. 如果PM中出现上述错误,请再次删除迁移文件夹,然后打开MySQL Workbench
  4. 在MySQL Workbench中,找到您在connectionString中给出的名称的Schema(看起来像database = whateverYouCalledIt
  5. 在该架构中,打开表格并找到“__migrationhistory”
  6. 右键单击该表,单击选择行,然后删除所有现有迁移条目,然后重复步骤2
  7. 由于某种原因,当解决方案资源管理器中的迁移删除无效时,这对我来说就是一个诀窍。显然,这并没有删除数据库中的迁移历史记录......

答案 1 :(得分:0)

以下步骤为我产生了相同的错误消息:

  1. 使用实体框架和SQL Server创建项目,并进行迁移。在模型类中使用一些不string的{​​{1}}属性,这些属性映射到MaxLength
  2. 重新配置MySQL,如上所述,用于空的MySQL数据库。
  3. 运行nvarchar(max)
  4. 在撰写本文时使用所有最新的软件版本库。

    收到错误后,我尝试在所有字符串属性上设置Update-Database。即使重新使用[MaxLength(..)]进行迁移,错误信息也会不断出现。

    在我的情况下,事实证明我的MySQL数据库上的Add-Migration Initial -Force调用(运行了针对SQL Server的旧迁移,包括Update-Database)导致了一些对我的数据库的影响,即正在创建的表,但不是全部。

    我的解决方案是:

    1. 删除这些表,确保数据库再次为空。
    2. nvarchar(max)
    3. Enable-Migrations -Force
    4. Add-Migration Initial -Force
    5. 请注意,这些步骤会覆盖对迁移和Update-Database功能的任何手动更改,您可能希望有选择地还原这些更改。

      在此之后,我测试了没有Seed()的字符串属性。这些可以与MySQL提供程序一起使用,它们映射到[MaxLength(..)]

答案 2 :(得分:0)

我遇到了同样的问题,发现根本原因是现有的迁移看起来像这样: AddColumn("dbo.RoundJumperMap", "VideoUrl", c => c.String());

一旦我找到所有这些并添加了maxlength,一切都很好。 AddColumn("dbo.RoundJumperMap", "VideoUrl", c => c.String(maxLength: 1000));

我不需要删除任何现有的迁移或类似的东西。