我是一名PHP / MySQL开发人员,试图转向其他技术,如.NET Core。我不确定我是否喜欢通过MySQL切换到SQL Server的想法(由于许可),所以我一直试图让.NET Core与MySQL很好地配合。
我已经使用Identity作为身份验证方法设置了一个相当基本的.NET Core 2.0项目,当数据库驱动程序SqlLite
与本地数据库时,一切正常。我尝试切换到MySQL
数据库并运行我的迁移但它们失败了。
我在尝试运行以下表创建查询时收到错误:Specified key was too long; max key length is 3072 bytes
:
CREATE TABLE `AspNetUserTokens` (
`UserId` varchar(767) NOT NULL,
`LoginProvider` varchar(767) NOT NULL,
`Name` varchar(767) NOT NULL,
`Value` text NULL,
PRIMARY KEY (`UserId`, `LoginProvider`, `Name`)
);
我的Mysql数据库使用UTF8mb4
的字符集,因此它不能使用上面指定的主键,大小约为9204字节。
如何自定义默认身份表的创建方式?如果可能的话,我想用这个表上更健全的主键替换庞大的键,这只是一个auto increment
整数。
有没有办法自定义如何创建默认的身份相关表,而无需手动黑客攻击文件。我可以用OnModelCreating
的{{1}}方法做任何事情吗?我应该停止与MySQL战斗并屈服于MS SQL吗?
修改
我能够使用Pomelo MySQL Driver而非Oracle来解决此问题。 Pomelo驱动程序似乎默认字符串字段最大长度为127个字符,这允许上面的键适合3072字节限制。但是,我仍然有兴趣知道如何微调和自定义.NETCore脚手架中提供的基本身份表。
答案 0 :(得分:4)
我不建议完全离开MySQL以解决这些问题。它现在已经是最常用的数据库了。既然您已经花时间处理这些问题并从中学习,那么尝试完整的循环并获得完整的理解是值得的。
就你使用柚子而言,你应该没问题。我建议坚持这一点。它确实有更多的git和nuget下载,也有更多的git明星。 Oracle的nuget,甚至是它的发布"版本仍未完成。据报道,它有未实现的功能https://bugs.mysql.com/bug.php?id=82981。如果MS正式提到官方提供商旁边的Pomelo
,它应该是真的。
关于您的主要问题,您应该可以在OnModelCreate
:
builder.Entity<ApplicationUser>()
.Property(u => u.Id)
.HasMaxLength(36);
请注意,根据IdentityUser<TKey>
类Id = Guid.NewGuid().ToString()
,它只需要36个字符。或者,您可以利用Id
是虚拟字段并在ApplicationUser
类中执行此操作的事实:
[MaxLength(36)]
public override string Id { get; set; }
另外,我并不是要反驳我所说的内容,但是对于某些项目来说,尝试SQL Server也没什么坏处。与MySQL相比,我确实在SQL Server中找到了几个便利。我不认为许可是不尝试SQL Server的原因。许多情况下许可并不重要,有几个原因。
答案 1 :(得分:4)
以下设置适用于具有自定义身份的 Asp.Net 5.0:
builder.Entity<AppUser>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<AppRole>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityUserClaim<string>>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityRoleClaim<string>>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityUserLogin<string>>(entity => entity.Property(m => m.LoginProvider).HasMaxLength(85));
builder.Entity<IdentityUserLogin<string>>(entity => entity.Property(m => m.ProviderKey).HasMaxLength(85));
builder.Entity<IdentityUserToken<string>>(entity => entity.Property(m => m.LoginProvider).HasMaxLength(85));
builder.Entity<IdentityUserToken<string>>(entity => entity.Property(m => m.Name).HasMaxLength(85));
我仅将 MaxLength
用于主键和索引。
答案 2 :(得分:0)
我只是想添加到@neville答案中,以便其他任何人使用默认的MySql.Data.EntityFrameworkCore nuget包来解决。
您需要在dbcontext OnModelCreating中添加以下键的最大长度,然后运行add-migration才能生效。
在此处创建了一个示例 https://github.com/k-siddharatha/DotNetCoreEFMySql
仅用于此问题。
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<IdentityUser>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityUser>(entity => entity.Property(m => m.NormalizedEmail).HasMaxLength(85));
builder.Entity<IdentityUser>(entity => entity.Property(m => m.NormalizedUserName).HasMaxLength(85));
builder.Entity<IdentityRole>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityRole>(entity => entity.Property(m => m.NormalizedName).HasMaxLength(85));
builder.Entity<IdentityUserLogin<string>>(entity => entity.Property(m => m.LoginProvider).HasMaxLength(85));
builder.Entity<IdentityUserLogin<string>>(entity => entity.Property(m => m.ProviderKey).HasMaxLength(85));
builder.Entity<IdentityUserLogin<string>>(entity => entity.Property(m => m.UserId).HasMaxLength(85));
builder.Entity<IdentityUserRole<string>>(entity => entity.Property(m => m.UserId).HasMaxLength(85));
builder.Entity<IdentityUserRole<string>>(entity => entity.Property(m => m.RoleId).HasMaxLength(85));
builder.Entity<IdentityUserToken<string>>(entity => entity.Property(m => m.UserId).HasMaxLength(85));
builder.Entity<IdentityUserToken<string>>(entity => entity.Property(m => m.LoginProvider).HasMaxLength(85));
builder.Entity<IdentityUserToken<string>>(entity => entity.Property(m => m.Name).HasMaxLength(85));
builder.Entity<IdentityUserClaim<string>>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityUserClaim<string>>(entity => entity.Property(m => m.UserId).HasMaxLength(85));
builder.Entity<IdentityRoleClaim<string>>(entity => entity.Property(m => m.Id).HasMaxLength(85));
builder.Entity<IdentityRoleClaim<string>>(entity => entity.Property(m => m.RoleId).HasMaxLength(85));
}
答案 3 :(得分:0)
更好的选择是 MaxLengthForKeys
为身份存储中的所有键设置此项(在 ConfigureServices
方法内)。
services.AddDefaultIdentity<User>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Stores.MaxLengthForKeys = 85;
})
.AddEntityFrameworkStores<ApplicationDbContext>();
这是文档中的注释
<块引用>如果设置为正数,默认的 OnModelCreating 将使用此值作为用作键的任何属性的最大长度,即 UserId、LoginProvider,