Ric*_*per 33 c# mysql entity-framework
[编辑]这个问题解决了!请参阅帖子末尾的说明.
[编辑2]好的,这个线程已经过时了,MySQL Connector的新版本已经使用MySQL EF解析器处理了这个问题.在这个帖子上寻找@KingPong的答案.不过,我还没有测试过.
我正在尝试使用MySql和EntityFramework进行迁移,但似乎有些错误.
当我进入Update-Database -Verbose
包管理器控制台时,EF执行一些将"镜像"我的模型类的查询,一切都很完美,但是EF尝试执行此查询:
create table `__MigrationHistory`
(
`MigrationId` varchar(150) not null
,`ContextKey` varchar(300) not null
,`Model` longblob not null
,`ProductVersion` varchar(32) not null
,primary key ( `MigrationId`,`ContextKey`)
) engine=InnoDb auto_increment=0
Run Code Online (Sandbox Code Playgroud)
结果是: Specified key was too long; max key length is 767 bytes
我试图将我的数据库排序规则更改为utf-8,但仍然相同.也许关键长度是450个字符,做UTF-8数学(我可能错了),我认为它试图创建一个大约1800字节长度的密钥.
由于我是EF的新手,我遵循了一些教程,他们告诉我这样做:
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
}
Run Code Online (Sandbox Code Playgroud)
也许这个SQL生成器做错了,或者EF本身要求生成器生成一个高达767字节的密钥.
我该如何解决这个问题,避免这个问题并让它与MySql一起使用?
[编辑] 好的,这个问题解决了.你必须告诉EF它必须改变它生成__MigrationHistory表的方式.
我做了什么:首先,MySqlHistoryContext.cs
用这个内容创建一个名为(或任何你想要的)文件:
...
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Migrations.History;
namespace [YOUR NAMESPACE].Migrations //you can put any namespace here, but be sure you will put the corret using statement in the next file. Just create a new class :D
{
public class MySqlHistoryContext : HistoryContext
{
public MySqlHistoryContext(DbConnection connection, string defaultSchema):base(connection,defaultSchema)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可能有一个名为Configuration.cs
您的内部Migrations
文件夹.如果是,请进行必要的调整,否则创建新文件.实际上,如果您没有此文件,您将无法获得此错误,因为EF会在您创建时自动创建它Add-Migration [name]
.
namespace [YOUR NAMESPACE].Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<CodeFirstMySql.Models.Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator()); //it will generate MySql commands instead of SqlServer commands.
SetHistoryContextFactory("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema)); //here s the thing.
}
protected override void Seed(CodeFirstMySql.Models.Context context){}//ommited
}
}
Run Code Online (Sandbox Code Playgroud)
然后Update-Database -Verbose
玩得开心!
ChA*_*33n 35
回答从添加自定义MigrationHistory上下文释义...
EF6使用MigrationHistory表来跟踪模型更改并确保数据库架构和概念架构之间的一致性.默认情况下,此表不适用于MySQL,因为主键太大.要解决此问题,您需要缩小该表的密钥大小.
从本质上讲,EF6允许您使用Fluent API修改MigrationId/ContextKey索引列的密钥大小,如下所示:
modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();
Run Code Online (Sandbox Code Playgroud)
Kin*_*ong 33
使用MySQL Connector/Net 6.8和Entity Framework版本6,您可以使用MySQL对EF的内置支持来解决此问题.诀窍是告诉实体框架使用MySQL解析器.来自Connector/Net开发人员指南:
这可以通过三种方式完成:
在上下文类中添加DbConfigurationTypeAttribute:
[DbConfigurationType(typeof(MySqlEFConfiguration))]在应用程序启动时调用DbConfiguration.SetConfiguration(new MySqlEFConfiguration())
在配置文件中设置DbConfiguration类型:
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">也可以创建自定义DbConfiguration类并添加所需的依赖项解析器.
当我按照这些说明(我使用配置文件方法)时,表已成功创建.它使用以下DDL:
create table `__MigrationHistory` (
`MigrationId` nvarchar(150) not null,
`ContextKey` nvarchar(300) not null,
`Model` longblob not null,
`ProductVersion` nvarchar(32) not null,
primary key ( `MigrationId`)
) engine=InnoDb auto_increment=0
Run Code Online (Sandbox Code Playgroud)
虽然ChAmp33n接受的答案解决了提问者提出的问题,但我认为在答案之后会有一些"破坏性"的变化.我已经应用了接受的答案,但例外仍然存在.
通过检查EF生成的SQL查询,我发现该问题与表AspNetRoles中的表AspNetUsers和Name(varchar utf8 256)中的UserName(varchar utf8 256)有关,而HistoryRow的表很好.
所以以下代码解决了这个问题.
public class WebPortalDbContext : IdentityDbContext<ApplicationUser>
{
public WebPortalDbContext()
: base("IdentityConnection")
{
}
public static WebPortalDbContext Create()
{
return new WebPortalDbContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>()
.Property(c => c.Name).HasMaxLength(128).IsRequired();
modelBuilder.Entity<Microsoft.AspNet.Identity.EntityFramework.IdentityUser>().ToTable("AspNetUsers")//I have to declare the table name, otherwise IdentityUser will be created
.Property(c => c.UserName).HasMaxLength(128).IsRequired();
}
}
Run Code Online (Sandbox Code Playgroud)
为了澄清解决方案,这里是我使用的库:
而这个解决方案也适用于
归档时间: |
|
查看次数: |
18252 次 |
最近记录: |