我有一个使用EF6代码的Azure MVC站点,它可以在MS SQL Server上完美地工作(在本地开发机器和ASP.NET网站/SQL上)。现在我正在将它转移到使用MySql 5.6dbs的产品中,这让我很头疼。
我的解决方案分为两层(web、视图模型、模型、数据层接口)和一个引用EF程序集的数据项目,这些层与持久性无关(使用UnitOfWork和GenericRepository)。
现在,我想我的解决方案应该将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>MySql连接器/网络版本为MySql.Data 6.8.3.0
我还将[DbConfigurationType(typeof(DbContextConfiguration))]添加到我的DbContext类中,并将SetExecutionStrategy(MySqlProviderInvariantName.ProviderName, () => new MySqlExecutionStrategy());添加到从MySqlEFConfiguration继承的DbContextConfiguration类中
我能够运行我的代码优先迁移(在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: 请注意
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.我束手无策。我不知道该怎么做,也不知道如何让EF与MySql提供商一起正常工作。一般来说,无论是在SO上还是在web上,这都没有什么用。我在http://forums.devart.com/viewtopic.php?t=24678上找到的都是关于Oracle DBS的类似内容
如果有任何想法,我将不胜感激。我开始想,如果我知道它可以解决这个问题,那么迁移到NHibernate会更好--我想知道这个问题是与EF映射实体和生成SQL语句的方式有关,还是与MySql提供者/连接器中的一些bug有关。
发布于 2016-03-06 00:12:57
如果您为SQL Server创建了迁移,然后将引擎更改为MySQL并尝试更新数据库,则会出现此问题。我通过以下方式解决了这个问题:
实体框架正在删除所有迁移classes
__migrationhistory mysql表(如果要使用实体框架,请使用MySQL
配置文件需要以下内容:
<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>DbContext类使用上面定义的名为PrimaryDatabase的连接字符串:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext() : base("PrimaryDatabase")
{
}
}最后,在迁移配置文件中:
internal sealed class Configuration : DbMigrationsConfiguration<MyProject.ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
}
}你可以在here上找到详细信息。
发布于 2014-03-08 07:47:39
您希望将应用程序与MySQL一起使用,但配置的默认连接工厂似乎是针对SqlServer的。因此,你得到的是SqlServer存储类型,而不是MySQL类型,这样事情就会崩溃。你应该使用MySQL连接工厂-查看这个线程Entity Framework 5.0 code-first with MySQL Connector 6.6.5.0 on .Net 4.5,他们在那里有所有的配置设置(包括MySQL特定的连接工厂)。
https://stackoverflow.com/questions/22262817
复制相似问题