带有EntityFramework 6架构错误0040的MySql 5.6

mr.*_*tan 5 c# mysql entity-framework ef-code-first

我有一个使用EF6代码的ASP.NET MVC站点,它可以完美地对抗MS SQL Server(在本地开发机器和Azure网站/ SQL上).现在我将它转移到使用MySql 5.6 DBS的生产中,这给我带来了麻烦.

我的解决方案分为多个层(Web,视图模型,模型,数据层接口),这些层是持久性无知的(使用UnitOfWork和GenericRepository)和引用EF程序集的单个数据项目.

现在我想我会将我的解决方案交换机EF提供程序从SQL Server分支到MySql.所以我添加了MySql.Data.Entities NuGet包并对web.config进行了以下更改:

<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  <providers>
    <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
  </providers>
</entityFramework>
Run Code Online (Sandbox Code Playgroud)

MySql Connector/Net版本是MySql.Data 6.8.3.0

我还添加[DbConfigurationType(typeof(DbContextConfiguration))]到我的DbContext类和SetExecutionStrategy(MySqlProviderInvariantName.ProviderName, () => new MySqlExecutionStrategy());我的DbContextConfiguration类,它继承自MySqlEFConfiguration

我能够运行我的代码优先迁移(借助于SetHistoryContextFactory(MySqlProviderInvariantName.ProviderName, (conn, schema) => new MySqlHistoryContext(conn, schema));)并创建数据库模式.

据我所知,数据库模式似乎是正确的.SQL Server中nvarchar的列是longtext或varchar(取决于实体属性上指定的最大长度),MySql和datetime2中的列是datetime.

现在,当我运行应用程序时,我收到以下异常:

System.Data.DataException was unhandled by user code
  HResult=-2146233087
  Message=An exception occurred while initializing the database. See the InnerException for details.
  Source=EntityFramework
  StackTrace:
       at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
       at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
       at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
       at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
       at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
       at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
       at System.Data.Entity.Internal.InternalContext.Initialize()
       at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
       at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
       at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
       at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
       at System.Linq.Queryable.Single[TSource](IQueryable`1 source, Expression`1 predicate)
       at Attendance.Web.Controllers.ControllerWithCurrentUser.GetCurrentUser() in .....
       at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive(Int32 filterIndex)
       at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.InvokeActionMethodFilterAsynchronouslyRecursive(Int32 filterIndex)
  InnerException: System.Data.Entity.Core.MetadataException
       HResult=-2146232007
       Message=Schema specified is not valid. Errors: 
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
       Source=EntityFramework
       StackTrace:
            at System.Data.Entity.Core.Metadata.Edm.StoreItemCollection.Loader.ThrowOnNonWarningErrors()
            at System.Data.Entity.Core.Metadata.Edm.StoreItemCollection.Loader.LoadItems(IEnumerable`1 xmlReaders, IEnumerable`1 sourceFilePaths)
            at System.Data.Entity.Core.Metadata.Edm.StoreItemCollection.Loader..ctor(IEnumerable`1 xmlReaders, IEnumerable`1 sourceFilePaths, Boolean throwOnError, IDbDependencyResolver resolver)
            at System.Data.Entity.Core.Metadata.Edm.StoreItemCollection.Init(IEnumerable`1 xmlReaders, IEnumerable`1 filePaths, Boolean throwOnError, IDbDependencyResolver resolver, DbProviderManifest& providerManifest, DbProviderFactory& providerFactory, String& providerInvariantName, String& providerManifestToken, Memoizer`2& cachedCTypeFunction)
            at System.Data.Entity.Core.Metadata.Edm.StoreItemCollection..ctor(IEnumerable`1 xmlReaders)
            at System.Data.Entity.Utilities.XDocumentExtensions.GetStorageMappingItemCollection(XDocument model, DbProviderInfo& providerInfo)
            at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy`1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator)
            at System.Data.Entity.Internal.InternalContext.ModelMatches(XDocument model)
            at System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata)
            at System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata)
            at System.Data.Entity.Database.CompatibleWithModel(Boolean throwIfNoMetadata)
            at System.Data.Entity.CreateDatabaseIfNotExists`1.<>c__DisplayClass1.<InitializeDatabase>b__0()
            at System.Data.Entity.Internal.MigrationsChecker.IsMigrationsConfigured(InternalContext internalContext, Func`1 databaseExists)
            at System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context)
            at System.Data.Entity.Internal.InternalContext.<>c__DisplayClasse`1.<CreateInitializationAction>b__d()
            at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
       InnerException: 
Run Code Online (Sandbox Code Playgroud)

请注意

Schema specified is not valid. Errors: 
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type datetime2 is not qualified with a namespace or alias. Only primitive types can be used without qualification.
(0,0) : error 0040: The Type nvarchar(max) is not qualified with a namespace or alias. Only primitive types can be used without qualification.
Run Code Online (Sandbox Code Playgroud)

我在我的智慧结束.无法弄清楚如何处理此问题或如何使EF与MySql提供程序正常工作.在SO或Web上一般没有任何用处.我在http://forums.devart.com/viewtopic.php?t=24678找到了与Oracle DBS类似的内容.

我会感激任何想法.我开始认为移动到NHibernate会更好,如果我知道它会解决这个问题 - 我想知道问题是否与EF如何映射实体并生成SQL语句或MySql提供者/连接器中的一些错误有关.

Mar*_*mro 5

当您为 SQL Server 创建了迁移,然后将引擎更改为 MySQL 并尝试更新数据库时,就会出现问题。我通过以下方式解决了这个问题:

  1. 删除所有迁移类
  2. 删除__migrationhistorymysql 表(如果存在)
  3. 配置实体框架以使用 MySQL
  4. 创建新的初始迁移。

配置文件需要这个:

<connectionStrings>
    <add name="PrimaryDatabase" providerName="MySql.Data.MySqlClient"
        connectionString="server=localhost;port=3306;database=mydatabase;uid=root;password=root"/>
</connectionStrings>
<entityFramework  codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
    <defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" />
    <providers>
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
    </providers>
</entityFramework>
<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.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
</system.data>
Run Code Online (Sandbox Code Playgroud)

DbContext 类使用名为 的连接字符串PrimaryDatabase,它在上面定义:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext() : base("PrimaryDatabase")
    {
    }

}
Run Code Online (Sandbox Code Playgroud)

最后在迁移配置文件中:

internal sealed class Configuration : DbMigrationsConfiguration<MyProject.ApplicationDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到详细信息。


Paw*_*wel 0

您希望将应用程序与 MySQL 一起使用,但配置的默认连接工厂似乎适用于 SqlServer。结果,您得到的是 SqlServer 存储类型而不是 MySQL 类型,并且事情发生了变化。您应该使用 MySQL 连接工厂 - 请参阅此线程Entity Framework 5.0 code-first with MySQL Connector 6.6.5.0 on .Net 4.5他们在那里有所有配置设置(包括 MySQL 特定的连接工厂)。