我将Firebird ADO.NET提供程序版本5.5与实体框架5一起使用。对于Firebird UTF-8数据库,LINQ to SQL查询的投影包括有条件地将字符串属性设置为常量会导致错误“实现限制”如果至少有两个提到的字符串投影存在,则块大小超出实现限制。
例如,我查询存储比萨饼的简单数据库:
var pizzerias =
from pizzeria in demoEntities.Pizzerias
select new
{
pizzeria.ID,
pizzeria.Name,
// Following two projections are the issue since Firebird add two times VARCHAR(8191) in case State and City are empty.
// It works with one of these projections, but not with two.
State = pizzeria.State != "CA" ? pizzeria.State : "-",
City = pizzeria.City != "Mountain View" ? pizzeria.City : "-"
};
州和城市的两个预测导致上述错误(如果只存在一个预测,则不会发生错误)。
生成的SQL将字符串常量转换为VARCHAR(8191),这很可能是导致错误的原因:
SELECT
"A"."ID" AS "ID",
"A"."NAME" AS "NAME",
CASE WHEN (CAST(_UTF8'CA' AS VARCHAR(8191)) <> "A"."STATE") THEN "A"."STATE" ELSE CAST(_UTF8'-' AS VARCHAR(8191)) END AS "C1",
CASE WHEN (CAST(_UTF8'Mountain View' AS VARCHAR(8191)) <> "A"."CITY") THEN "A"."CITY" ELSE CAST(_UTF8'-' AS VARCHAR(8191)) END AS "C2"
FROM "PIZZERIAS" AS "A"
直接对数据库执行SQL(使用IBExpert)时会抛出相同的错误。
奇怪的是,在使用Win1252编码的相同数据库上不会发生此错误。
顺便说一句:我知道样本中的预测没有意义,我可以轻松解决问题。但是在一个更复杂的场景中我遇到了类似的问题,我无法轻松解决这个问题。
我想了解这里发生了什么,以及为什么Win1252数据库上不会出现问题。一种解决方案是在投影中使用较小的VARCHAR,但我不知道如何告诉ADO.NET Firebird提供程序执行此操作。