由于实体框架 6.1.3 使用 nvarchar(MAX)
作为字符串的默认值,因此我不想将其更改为nvarchar(256)
。您可以在下面的链接中阅读有关nvarchar(MAX)
损害性能的原因的更多信息。简短的回答是索引。
https://dba.stackexchange.com/questions/48408/ef-code-first-uses-nvarcharmax-for-all-strings-will-this-hurt-query-performan
我通过将这一行添加到OnModelCreating
来做到这一点:
modelBuilder.Properties<string>().Configure(s =>
s.HasMaxLength(256).HasColumnType("nvarchar"));
但是,这也会影响IdentityDbContext
(个人用户帐户(自动创建的列。
具体来说dbo.AspNetUsers.PasswordHash
、dbo.AspNetUsers.SecurityStamp
、dbo.AspNetUserClaims.ClaimType
和dbo.AspNetUserClaims.ClaimValue
。对于这些,我仍然不想使用nvarchar(MAX)
.
对于我有权访问的属性,我可以使用列属性,这将被修复。例:
[Column(TypeName = "nvarchar(MAX)")]
public string CaseComment { get; set; }
我想我必须使用流畅的 API 来解决这个问题,但我该怎么做呢?
在这里找到我的答案:
https://learn.microsoft.com/en-us/ef/core/modeling/relational/columns
modelBuilder.Entity<ApplicationUser>()
.Property(b => b.PasswordHash)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<ApplicationUser>()
.Property(b => b.SecurityStamp)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<ApplicationUserClaim>()
.Property(b => b.ClaimType)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<ApplicationUserClaim>()
.Property(b => b.ClaimValue)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
ApplicationUserClaim
这是因为我们在应用程序中使用自定义声明。默认值为:
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.ClaimType)
.HasColumnType("nvarchar(MAX)");
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.ClaimValue)
.HasColumnType("nvarchar(MAX)");
更新 2
对所有字符串使用覆盖,如下所示:
modelBuilder.Properties<string>().Configure(s =>
s.HasMaxLength(256).HasColumnType("nvarchar"));
然后使用如下所示的属性修改属性:
[Column(TypeName = "nvarchar(MAX)")]
public string CaseComment { get; set; }
或者这个:
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.ClaimType)
.HasColumnType("nvarchar(MAX)");
这可能会导致异常。 Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
即使该列的数据类型正确,实体框架仍然认为它是nvarchar(256)
的,并抛出错误DbEntityValidationException
。
要解决此问题,请改用以下命令:
[Column(TypeName = "nvarchar(MAX)")]
[MaxLength]
public string CaseComment { get; set; }
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.ClaimType)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
更新:
如果您有标准ApplicationUser
并且不想保持原样但仍不nvarchar(256)
为标准,则可以使用以下设置:
modelBuilder.Entity<ApplicationUser>()
.Property(b => b.Id)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<ApplicationUser>()
.Property(b => b.PasswordHash)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<ApplicationUser>()
.Property(b => b.SecurityStamp)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<ApplicationUser>()
.Property(b => b.PhoneNumber)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<IdentityRole>()
.Property(b => b.Id)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserRole>()
.Property(b => b.UserId)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserRole>()
.Property(b => b.RoleId)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserLogin>()
.Property(b => b.UserId)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserLogin>()
.Property(b => b.LoginProvider)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserLogin>()
.Property(b => b.ProviderKey)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.UserId)
.HasColumnType("nvarchar")
.HasMaxLength(128);
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.ClaimType)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);
modelBuilder.Entity<IdentityUserClaim>()
.Property(b => b.ClaimValue)
.HasColumnType("nvarchar(MAX)")
.HasMaxLength(null);