【发布时间】:2020-07-16 16:55:30
【问题描述】:
我有一个旧版 Firebird (2.5.9) 数据库,它是在没有字符集的情况下创建的,因为它是在生产中,所以所有数据都是使用 WIN1252 插入的。我正在迁移到 .Net Core,并使用 FirebirdSql.Data.FirebirdClient 作为提供者(在 .Net Framework 和 .Net Core 中)。
在 .Net Framework 和 EF 6 中,我只需在连接字符串中设置字符集 WIN1252。
在 .Net Core 3.1 中,连接字符串的字符集仅在读取时使用,因为我必须首先在代码中设置列类型,如下所示:
entity.Property(e => e.description).HasMaxLength(255).HasColumnType("VARCHAR(255) CHARACTER SET WIN1252");
使其以相同的编码保存字符串。
我现在面临的问题与所有查询参数似乎都使用 UTF8 的事实有关,这是 .Net Core 中新的默认编码,并且一些特殊字符当然是不同的。
因此,例如,假设我在字段 description 中有一条带有重音字符的记录,例如“èèè”。
以下查询检索失败:
string filter = "èèè";
Product p = context.Products.Where(x => x.description == filter).FirstOrDefault();
这个查询被翻译成:
SELECT "a"."product_id", ... , "a"."description"
FROM "products" AS "a"
WHERE "a"."description" = CAST(@__filter_0 AS VARCHAR(8191))
这种转换也发生在 .Net Framework 中,但像这样的查询在那里可以正常工作。
另外,如果有多个参数我会得到错误
Implementation limit exceeded. block size exceeds implementation restriction
这正是question 中描述的内容,即使那是在 EF5 和 .Net Framework 中。基本上,您似乎很容易达到 64k 的行大小限制,因为 VARCHAR(8191) 在字节方面将权重转换为 UTF8。
我确信一种解决方案是升级到使用 UTF8 编码的新数据库并正确编码所有数据,但目前我希望尽可能避免这种情况。另外我认为这不会解决块大小错误。
有没有办法让它像在 .Net Framework 中一样工作?
【问题讨论】:
-
Firebird 问题DNET-934:将字符串值转换为 VARCHAR(8191) 导致“超出实施限制” 似乎与您所描述的有关。不确定这是否有助于提供我遇到的似乎切线相关的东西。
-
@ahsteele 是的,它与块大小限制有关。不幸的是,当我使用提供程序选项禁用强制转换时,需要调查许多新的“数据类型未知”错误
-
“连接字符串的字符集仅在阅读时使用”,这与我对 Firebird 有线协议的理解不符。我建议您在firebird-net-provider Google Group 上提问。
-
Firebird (2.5.9) database that was created with no charset- 你能编辑系统表并在其中追溯引入字符集吗?它可能还需要刷新更改,例如备份-恢复周期或制作使用propr charset连接的简单应用程序,然后在所有表上发出UPDATE T SET X=X, Y=Y, Z=Z(脚本可以使用这些系统表自动生成) -
@MarkRotteveel 我在那里发帖,我会在这里分享我的发现。谢谢。
标签: c# .net-core entity-framework-core firebird firebird2.5