c# - EF Core 压缩解压栏
问题描述
以一个简单的 poco 为例,它带有一个ID和一个名为data的字符串属性。
在使用EF CoreCOMPRESS(data)
保存实体并调用加载它之前,最好的调用方式是什么。数据库列当然是 VARBINARY。DECOMPRESS(data)
详细的:
编写自定义 SQL 来实现这一点(基于上面的示例)如下所示:
SELECT Id, DECOMPRESS(@Data) as [Data]
FROM table
用于选择并像这样插入实体:
INSERT INTO table
VALUES(@Id, COMPRESS(@Data))
笔记:
它是 SQL 服务器。
当前的字符串长度可以达到几千,因为NVARCHAR
在 DB 端使用 PAGE 或 ROW 压缩的固定长度不是一个选项。
解决方案
使用转换似乎是最好的方法。因为越早压缩数据,生成的网络 I/O 就越少。此外,压缩会消耗宝贵的 SQL Server CPU 周期,并可能影响 SQL Server 的性能。
public class YourEntityTypeConfigruation : IEntityTypeConfiguration<YourEntity>
{
public void Configure(EntityTypeBuilder<YourEntity> builder)
{
builder.Property(e => e.Data)
.HasConversion(
v => Zip(v),
v => Unzip(v));
}
public static void CopyTo(Stream src, Stream dest) {
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
dest.Write(bytes, 0, cnt);
}
}
public static byte[] Zip(string str) {
var bytes = Encoding.UTF8.GetBytes(str);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray();
}
}
public static string Unzip(byte[] bytes) {
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
}
当您创建类似的视图时,可以使用 SQL 服务器方法
CREATE VIEW MyView
AS
SELECT Id, DECOMPRESS(Data) as [Data]
FROM table
并将其映射到 EF 上下文中
对于插入/更新,您需要存储过程来压缩数据。打破使用实体框架跟踪实体更改的目的。
推荐阅读
- javascript - npm 的 docker-compose up 失败
- python - django url 可以在开头包含固定路径吗?
- android - 如何使用绑定适配器从 ImageView 中的 drawable 加载动画 gif?
- java - 无法为元素 Appenders 调用类 org.apache.logging.log4j.core.config.AppendersPlugin 中的工厂方法:java.lang.NullPointerException
- swift - 计算两个坐标之间的距离并将其显示在 UITableViewCell 的标签内
- java - 何时使用接口变量与实现变量
- elasticsearch - 在 Kibana 仪表板中使用 SQL
- python - 为什么我要为 Python 中数据框的每个索引获取列标题?
- c++ - 冒泡排序降序
- javascript - laravel 在提交表单时没有获取文件