在 C# 中压缩并在 LINQ To Entities 中解压

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

我有这个问题:我正在尝试压缩一条来自“外部”的信息并将其存储到最大长度为 255 个字符的数据库表(由 EF 6.x 管理)中。

我正在使用 C#,框架 4.7.2.

到目前为止,很容易。 “问题”是,一旦它在数据库中,我需要将它读取(并解压缩/使其再次可读)到 LINQ To Entities 查询中。 因此,如果我不想具体化查询(而且我不能),我需要对其进行巧妙处理并以一种我可以使用 LINQ To 中可供我使用的有限功能将其取回的方式进行压缩实体

你有什么建议吗?到目前为止,我还没有找到适合这种情况的广告 SqlFunctions 或 DbFunctions 类。

谢谢

c# entity-framework linq linq-to-entities
1个回答
0
投票

只要你不需要检查查询本身的压缩值,例如期望使用压缩字符串的内容过滤

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 值发生变化时设法保持同步。

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