在始终加密的列值上使用 ToLower() 的 Linq 查询返回错误

问题描述 投票:0回答:1

我已通过 SSMS 在数据库中配置了“始终加密”列。我有一个 linq 查询,它只是检查我传递的字符串是否与具有相同字符串的任何记录匹配。

这个 linq 查询有效:

appDbContext.Users.FirstOrDefault(x => x.Email == userEmail);

但是,除非转换为大写/小写,否则我不能依赖精确的字符串比较。也就是说,这个 linq 查询不起作用:

appDbContext.Users.FirstOrDefault(x => x.Email.ToLower() == userEmail.ToLower());

具体错误是:

Microsoft.Data.SqlClient.SqlException:'操作数类型冲突: nvarchar(100) 使用 (encryption_type = 'DETERMINISTIC', 加密算法名称 = 'AEAD_AES_256_CBC_HMAC_SHA_256', 列_加密_密钥_名称 = 'CEK_Auto1', column_encryption_key_database_name = 'MyDatabaseName') 与 无法准备 varchar 语句。'

任何人都可以告诉我为什么会发生这种情况或者我该如何解决这个问题吗?

c# linq always-encrypted
1个回答
0
投票

ToLower()
翻译为对
LOWER
的调用。您不能在加密列上使用
LOWER
或任何其他函数,因为服务器(根据设计)无法解密它,只有客户端可以做到这一点。对于服务器来说,它基本上是一个完整的黑匣子。

您可以对加密列做的唯一实际操作是将其返回给客户端。如果使用确定性加密(安全性稍差),那么您还可以进行相等过滤器和联接以及分组。但是您不能对该值执行任何其他操作,例如串联、函数调用、排序规则更改等。您甚至不能使用

>
LIKE
,因为这需要服务器知道数据的固有排序,并且您无法将其与另一个表或变量中的未加密值进行比较。

请注意,您也不能使用不区分大小写的排序规则,因为服务器无法在不知道实际值的情况下处理此类排序规则的排序和过滤。

最好的选择是一开始就以小写形式存储。

© www.soinside.com 2019 - 2024. All rights reserved.