以一个带有 ID 和一个名为 data 的字符串属性的简单poco为例。
在使用 EF Core 保存实体并在加载实体时调用COMPRESS(data)
之前,调用DECOMPRESS(data)
的最佳方法是什么。数据库列当然是VARBINARY。
详细信息:
编写自定义SQL实现此目的(基于上述示例)如下所示:
SELECT Id, DECOMPRESS(@Data) as [Data]
FROM table
用于选择,并类似地用于插入实体:
INSERT INTO table
VALUES(@Id, COMPRESS(@Data))
注释:
这是SQL Server。
当前的字符串长度可以增加到几千,因为在数据库侧使用PAGE或ROW压缩的固定长度NVARCHAR
并不是一种选择。
答案 0 :(得分:1)
使用转换似乎是最好的方法。由于压缩数据越早,生成的网络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 Server方法
CREATE VIEW MyView
AS
SELECT Id, DECOMPRESS(Data) as [Data]
FROM table
然后mapping在EF上下文中
对于插入/更新,您将需要存储过程来压缩数据。达到了使用实体框架跟踪实体更改的目的。