我有这个问题:我正在尝试压缩一条来自“外部”的信息并将其存储到最大长度为 255 个字符的数据库表(由 EF 6.x 管理)中。
我正在使用 C#,框架 4.7.2.
到目前为止,很容易。 “问题”是,一旦它在数据库中,我需要将它读取(并解压缩/使其再次可读)到 LINQ To Entities 查询中。 因此,如果我不想具体化查询(而且我不能),我需要对其进行巧妙处理并以一种我可以使用 LINQ To 中可供我使用的有限功能将其取回的方式进行压缩实体
你有什么建议吗?到目前为止,我还没有找到适合这种情况的广告 SqlFunctions 或 DbFunctions 类。
谢谢
只要你不需要检查查询本身的压缩值,例如期望使用压缩字符串的内容过滤
Where
子句等,那么你可以将压缩/解压委托给C#辅助方法。您无需“具体化”整个实体/图形即可获得价值,只需在检索完所需实体或完成投影后执行解压即可。
例如我为压缩和解压创建了一个静态辅助方法:
public static string CompressString(string source)
{ ... }
public static string DecompressString(string source)
{ ... }
在数据库中你可能有一个名为“BigString”的值,所以在实体中我们可以有一个 BigString 属性,如果实体的消费者永远不需要看到压缩值,我们可以将它标记为
protected
。然后我们可以公开一个 BigString 的非映射解压缩版本,它按需解压缩我们的值:
public class SomeEntityWithBigString
{
// ...
protected string BigString { get; set; }
private string? _decompressedBigString = null;
[NotMapped]
public string DecompressedBigString
{
get { return _decompressedBigString ??= Compressor.DecompressString(BigString); }
set
{
_decompressedBigString = value;
BigString = Compressor.CompressString(value);
}
}
}
类似地,如果你想将 BigString 投影到 ViewModel 或 DTO 中,你可以在 ViewModel 中使用类似的属性方法来执行解压缩。您将投射出原始 BigString 值,然后 ViewModel 有一个访问器来显示解压缩后的值。您无需具体化整个实体等即可返回压缩数据。
正如我在评论中提到的,这种方法的警告是您不能查询解压后的值。因此,如果字符串包含要过滤的关键字或类似关键字,则不能在
Where
子句之类的内容中使用它。在大字符串中搜索值非常昂贵,因此如果这是一个要求,那么您最好引入架构更新以将可搜索的关键字拆分为一对多的 SomeEntityKeyWords 关系,其中大文本可以拆分为多个可搜索和可索引的术语,然后在 BigString 值发生变化时设法保持同步。