始终加密的 SQL 2016 和实体框架 6:"操作数类型冲突:datetime2 与日期不兼容"



当前项目:

  • MVC 5.2
  • 点网 4.6.2
  • EF 6
  • 标识 2(根据以下存储库模式修改)
  • SQL Server 2016 RTM
  • 存储库模式:持久性无知 ASP.NET 标识
  • 始终加密列加密,如此处和此处所述
  • 所有 SQL 都EntityTypeConfigurationMapToStoredProcedures();

与存储库模式教程不同,我能够将我的模型推送到数据库。我不是在手工组装的数据库上工作。我确实根据第二个始终加密链接中的两个SQL语句修改了迁移,对于出生日期和社会安全号码也不足为奇。

因为我的实体框架实体这样指定加密字段,

Property(x => x.Dob).HasColumnOrder(15).HasColumnName("Dob").HasColumnType("Date").IsRequired();
Property(x => x.Sin).HasColumnOrder(16).HasColumnName("Sin").HasColumnType("nvarchar").HasMaxLength(11).IsRequired();

我通过以下方式在User域实体中装饰了这两个字段:

[DataType(DataType.Date)]
public DateTime Dob { get; set; }
[MaxLength(11)]
public string Sin { get; set; }

根据此评论。作为预防措施,我还在IdentityUser.cs文件中装饰了相同的字段。

当我尝试推送我尝试创建的默认管理用户时,使用以下命令:

public async Task<ActionResult> AddAdmin() {
var user = _userManager.FindByName("email@domain.net");
if(user == null) {
user = new IdentityUser() {
// Other fields
Dob = new DateTime(1972, 10, 12),
Sin = "726-261-050",
// Other fields
};
var createUser = await _userManager.CreateAsync(user, "password");
if (createUser.Succeeded) {
var userId = _userManager.FindByName("email@domain.net").Id;
var addRole = await _userManager.AddToRoleAsync(userId, "Admin");
if (addRole.Succeeded) {
return View("Index");
}
}
}
}

我收到以下错误:

操作数类型冲突:datetime2(7) 加密使用 (encryption_type = "随机",encryption_algorithm_name = "AEAD_AES_256_CBC_HMAC_SHA_256", column_encryption_key_name = "CEK1", column_encryption_key_database_name = '数据库') 与 加密日期为 (encryption_type = "随机", encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK1', column_encryption_key_database_name = '数据库')

这发生在_userManager.CreateAsync().

我完全不知道为什么会发生这种情况。我已经明确指定DobIdentityUser()Date领域,而不是DateTime2.原始User模型/域及其关联的 EF 实体也是如此。实际的数据库字段是一个Date字段(亲自确认了这一点),所以我可以看到如果源被神秘地创建为DateTime2,为什么目的地是一个问题,即使IdentityUser()Dob字段也是一个Date。从理论上讲,IdentityUser()中的Date字段不能将DateTime2传递给数据库。

我相信EF将所有日期类型处理为datetime2。将 SQL 服务器中的列类型更改为 datetime2 应该会有所帮助。截至目前,唯一的选择是在 SQL Server 中将列的数据类型更改为 datetime2,因为 EF 没有任何与参数生成的挂钩。

如果我们不想将 的数据类型从datetime更改为datetime2. 因为日期时间将最后一个小数点后的 7 位数字扩展。

通过以下脚本进行检查。 黑白日期时间和日期时间的差异2。

select * from newdatetimetest ALTER TABLE newdatetimetest ALTER column mydatetime datetime2

select * from newdatetimetest ALTER TABLE newdatetimetest ALTER column mydatetime datetime

select * from newdatetimetest

您可以实现自定义拦截器以将实体框架 datetime2 数据类型转换为日期时间。

我们已经成功实施并成功插入记录。

在链接下方找到参考表格。

https://github.com/aspnet/EntityFramework6/issues/578

https://github.com/aspnet/EntityFramework6/pull/1147

最新更新