.NET - 在 Visual FoxPro 中使用 Entity Framework - 错误 "Compiled code for this line is too long."
.NET - using Entity Framework with Visual FoxPro - error "Compiled code for this line is too long."
我正在尝试将 Entity Framework 6 (EF) 与 Visual FoxPro 数据库一起使用(使用来自 NuGet 的包 VFPEntityFrameworkProvider2),我能够很好地建立连接。我能够从大多数表中加载数据。
当我尝试检索具有大约 240 个字段的特定类型的 DbSet 时出现问题。抛出的异常包含消息:
Compiled code for this line is too long.
据我所知,EF 编写了 SQL select 语句来检索数据,并且此语句太长。当我使用调试器检查局部变量时,我看到一个 SQL 语句,其长度接近 16000 个字符,而 maximum allowed command length for VFP is 8,192 bytes
我不太确定如何解决这个问题,因为我对 EF 还很陌生。我想我可以编辑一些生成的代码,或者编写一些自定义处理程序。也许我可以批量检索字段,然后组合对象。
此外,我相信可以将我的实体分解为类型和子类型;也许如果我这样做,一次只会检索一部分字段。
谁能建议我用什么方式解决这个限制?
添加的注释:
不能选择使用不同的数据库。我坚持使用 FoxPro 和这个特定的架构。但是,我可以自由地改变解决问题的方法。当然,我可以自己写DB访问代码,但是如果能用EF就更好了。
发送到 VFP 的查询实际上看起来像这样:
SELECT
E1.Wn_Ref,
E1.Wn_Surname,
E1.Wn_Forenam,
E1.Wn_Dirctr,
...
E1.Wn_Chqno,
CAST( E1.Wn_Lelval AS n(20,2)) AS Wn_Lelval,
E1.Wn_Dirstpd,
...
E1.Wn_Leavdt,
CAST( E1.Wn_Grsprv AS n(20,2)) AS Wn_Grsprv,
CAST( E1.Wn_Taxprv AS n(20,2)) AS Wn_Taxprv,
E1.Wn_Ovride,
E1.Wn_Nichgpr,
...
E1.Wn_Totabs,
CAST( E1.Wn_Tgrspay AS n(20,2)) AS Wn_Tgrspay,
CAST( E1.Wn_Tottax AS n(20,2)) AS Wn_Tottax,
CAST( E1.Wn_Totpens AS n(20,2)) AS Wn_Totpens,
CAST( E1.Wn_Totsspr AS n(20,2)) AS Wn_Totsspr,
CAST( E1.Wn_Totsmp AS n(20,2)) AS Wn_Totsmp,
CAST( E1.Wn_Totchrt AS n(20,2)) AS Wn_Totchrt,
CAST( E1.Wn_Totcmee AS n(20,2)) AS Wn_Totcmee,
CAST( E1.Wn_Totcmer AS n(20,2)) AS Wn_Totcmer,
CAST( E1.Wn_Tcmeeyr AS n(20,2)) AS Wn_Tcmeeyr,
CAST( E1.Wn_Tcmeryr AS n(20,2)) AS Wn_Tcmeryr,
CAST( E1.Wn_Totpenl AS n(20,2)) AS Wn_Totpenl,
CAST( E1.Wn_Totpay AS n(20,2)) AS Wn_Totpay,
CAST( E1.Wn_Tothol AS n(20,1)) AS Wn_Tothol,
CAST( E1.Wn_Roundbf AS n(20,2)) AS Wn_Roundbf,
E1.Wl_Totsspd,
E1.Wl_Totabs,
CAST( E1.Wl_Tgrspay AS n(20,2)) AS Wl_Tgrspay,
CAST( E1.Wl_Tottax AS n(20,2)) AS Wl_Tottax,
CAST( E1.Wl_Totpens AS n(20,2)) AS Wl_Totpens,
CAST( E1.Wl_Totsspr AS n(20,2)) AS Wl_Totsspr,
CAST( E1.Wl_Totsmp AS n(20,2)) AS Wl_Totsmp,
CAST( E1.Wl_Totchrt AS n(20,2)) AS Wl_Totchrt,
CAST( E1.Wl_Totcmee AS n(20,2)) AS Wl_Totcmee,
CAST( E1.Wl_Totcmer AS n(20,2)) AS Wl_Totcmer,
CAST( E1.Wl_Tcmeeyr AS n(20,2)) AS Wl_Tcmeeyr,
CAST( E1.Wl_Tcmeryr AS n(20,2)) AS Wl_Tcmeryr,
CAST( E1.Wl_Totpenl AS n(20,2)) AS Wl_Totpenl,
CAST( E1.Wl_Totpay AS n(20,2)) AS Wl_Totpay,
CAST( E1.Wl_Tothol AS n(20,1)) AS Wl_Tothol,
CAST( E1.Wl_Txb AS n(20,2)) AS Wl_Txb,
CAST( E1.Wl_Tax AS n(20,2)) AS Wl_Tax,
CAST( E1.Wl_Net AS n(20,2)) AS Wl_Net,
CAST( E1.Wl_Erni AS n(20,2)) AS Wl_Erni,
CAST( E1.Wl_Eeni AS n(20,2)) AS Wl_Eeni,
CAST( E1.Wl_Cnoni AS n(20,2)) AS Wl_Cnoni,
CAST( E1.Wl_Nien AS n(20,2)) AS Wl_Nien,
CAST( E1.Wl_Nieco AS n(20,2)) AS Wl_Nieco,
CAST( E1.Wl_Compee AS n(20,2)) AS Wl_Compee,
CAST( E1.Wl_Comper AS n(20,2)) AS Wl_Comper,
CAST( E1.Wl_Pen AS n(20,2)) AS Wl_Pen,
CAST( E1.Wl_Penbl AS n(20,2)) AS Wl_Penbl,
CAST( E1.Wl_Roundcf AS n(20,2)) AS Wl_Roundcf,
CAST( E1.Wn_Ssp1 AS n(20,2)) AS Wn_Ssp1,
CAST( E1.Wn_Ssp2 AS n(20,2)) AS Wn_Ssp2,
CAST( E1.Wn_Ssp3 AS n(20,2)) AS Wn_Ssp3,
CAST( E1.Wn_Ssp4 AS n(20,2)) AS Wn_Ssp4,
CAST( E1.Wn_Ssp5 AS n(20,2)) AS Wn_Ssp5,
CAST( E1.Wn_Ssp6 AS n(20,2)) AS Wn_Ssp6,
CAST( E1.Wn_Ssp7 AS n(20,2)) AS Wn_Ssp7,
CAST( E1.Wn_Ssp8 AS n(20,2)) AS Wn_Ssp8,
E1.Wn_Ssprate,
...
E1.Wn_Pwxretn
FROM (SELECT
Wname.Wn_Ref,
...
Wname.Wn_Chqno,
CAST( Wname.Wn_Lelval AS n(20,2)) AS Wn_Lelval,
Wname.Wn_Dirstpd,
Wname.Wn_Payfrq,
Wname.Wn_Birth,
Wname.Wn_Startdt,
Wname.Wn_Leavdt,
CAST( Wname.Wn_Grsprv AS n(20,2)) AS Wn_Grsprv,
CAST( Wname.Wn_Taxprv AS n(20,2)) AS Wn_Taxprv,
Wname.Wn_Ovride,
...
Wname.Wn_Totabs,
CAST( Wname.Wn_Tgrspay AS n(20,2)) AS Wn_Tgrspay,
CAST( Wname.Wn_Tottax AS n(20,2)) AS Wn_Tottax,
CAST( Wname.Wn_Totpens AS n(20,2)) AS Wn_Totpens,
CAST( Wname.Wn_Totsspr AS n(20,2)) AS Wn_Totsspr,
CAST( Wname.Wn_Totsmp AS n(20,2)) AS Wn_Totsmp,
CAST( Wname.Wn_Totchrt AS n(20,2)) AS Wn_Totchrt,
CAST( Wname.Wn_Totcmee AS n(20,2)) AS Wn_Totcmee,
CAST( Wname.Wn_Totcmer AS n(20,2)) AS Wn_Totcmer,
CAST( Wname.Wn_Tcmeeyr AS n(20,2)) AS Wn_Tcmeeyr,
CAST( Wname.Wn_Tcmeryr AS n(20,2)) AS Wn_Tcmeryr,
CAST( Wname.Wn_Totpenl AS n(20,2)) AS Wn_Totpenl,
CAST( Wname.Wn_Totpay AS n(20,2)) AS Wn_Totpay,
CAST( Wname.Wn_Tothol AS n(20,1)) AS Wn_Tothol,
CAST( Wname.Wn_Roundbf AS n(20,2)) AS Wn_Roundbf,
Wname.Wl_Totsspd,
Wname.Wl_Totabs,
CAST( Wname.Wl_Tgrspay AS n(20,2)) AS Wl_Tgrspay,
CAST( Wname.Wl_Tottax AS n(20,2)) AS Wl_Tottax,
CAST( Wname.Wl_Totpens AS n(20,2)) AS Wl_Totpens,
CAST( Wname.Wl_Totsspr AS n(20,2)) AS Wl_Totsspr,
CAST( Wname.Wl_Totsmp AS n(20,2)) AS Wl_Totsmp,
CAST( Wname.Wl_Totchrt AS n(20,2)) AS Wl_Totchrt,
CAST( Wname.Wl_Totcmee AS n(20,2)) AS Wl_Totcmee,
CAST( Wname.Wl_Totcmer AS n(20,2)) AS Wl_Totcmer,
CAST( Wname.Wl_Tcmeeyr AS n(20,2)) AS Wl_Tcmeeyr,
CAST( Wname.Wl_Tcmeryr AS n(20,2)) AS Wl_Tcmeryr,
CAST( Wname.Wl_Totpenl AS n(20,2)) AS Wl_Totpenl,
CAST( Wname.Wl_Totpay AS n(20,2)) AS Wl_Totpay,
CAST( Wname.Wl_Tothol AS n(20,1)) AS Wl_Tothol,
CAST( Wname.Wl_Txb AS n(20,2)) AS Wl_Txb,
CAST( Wname.Wl_Tax AS n(20,2)) AS Wl_Tax,
CAST( Wname.Wl_Net AS n(20,2)) AS Wl_Net,
CAST( Wname.Wl_Erni AS n(20,2)) AS Wl_Erni,
CAST( Wname.Wl_Eeni AS n(20,2)) AS Wl_Eeni,
CAST( Wname.Wl_Cnoni AS n(20,2)) AS Wl_Cnoni,
CAST( Wname.Wl_Nien AS n(20,2)) AS Wl_Nien,
CAST( Wname.Wl_Nieco AS n(20,2)) AS Wl_Nieco,
CAST( Wname.Wl_Compee AS n(20,2)) AS Wl_Compee,
CAST( Wname.Wl_Comper AS n(20,2)) AS Wl_Comper,
CAST( Wname.Wl_Pen AS n(20,2)) AS Wl_Pen,
CAST( Wname.Wl_Penbl AS n(20,2)) AS Wl_Penbl,
CAST( Wname.Wl_Roundcf AS n(20,2)) AS Wl_Roundcf,
CAST( Wname.Wn_Ssp1 AS n(20,2)) AS Wn_Ssp1,
CAST( Wname.Wn_Ssp2 AS n(20,2)) AS Wn_Ssp2,
CAST( Wname.Wn_Ssp3 AS n(20,2)) AS Wn_Ssp3,
CAST( Wname.Wn_Ssp4 AS n(20,2)) AS Wn_Ssp4,
CAST( Wname.Wn_Ssp5 AS n(20,2)) AS Wn_Ssp5,
CAST( Wname.Wn_Ssp6 AS n(20,2)) AS Wn_Ssp6,
CAST( Wname.Wn_Ssp7 AS n(20,2)) AS Wn_Ssp7,
CAST( Wname.Wn_Ssp8 AS n(20,2)) AS Wn_Ssp8,
Wname.Wn_Ssprate,
...
FROM Wname Wname) E1
虽然您可能无法选择数据库,但您可以选择 Entity Framework 吗?我发现使用 Dapper 更适合这种情况,并且可以让您对查询进行低级控制。
sql 语句可能超过 8000+ 限制的原因有很多。作为 VFP EF Provider 的作者,鉴于 VFP 和 Entity Framework 之间的各种限制,我已经尝试尽可能减少 sql 语句。但是 240 个字段没有太多回旋余地。就我个人而言,我会接受 Cetin Basoz 的建议,即通过创建多个 类 来将其视为多个 table,这些 类 代表 table 到 trim 的一部分 sql 语句。或者,您可以使用 LINQ Select 操作只提供字段的子集。那应该为您减少语句,使其不超过 8000+ 限制。
(取消对你的 linq 语句的假设,因为它没有显示......)
如果您确实需要所有列,那么您可能想尝试在仅获取主键的查询和使用主键 return 所有字段的查询之间分解查询。这可能对你有用。
我自己的回答:在处理了一段时间后,我发现 tables 以只读方式添加到 EDMX 模型中。这意味着它是 selecting 来自 select 语句,这是多余的,并且膨胀了 select 语句的大小。当我手动编辑 EDMX 文件并强制其将 table 视为可读写时,问题消失了。
此外,在 Tom 的建议下,我开始更好地欣赏代码优先方法。我完全取消了 EDMX 模型。我发现这更容易管理,因为我通过模型的 class 属性上的属性控制每个字段的处理方式。使用代码优先,我对上下文 classes 的自定义不可能被覆盖;这对我来说是完美的,因为我需要自定义构造函数并覆盖 SaveChanges 和其他方法。
我正在尝试将 Entity Framework 6 (EF) 与 Visual FoxPro 数据库一起使用(使用来自 NuGet 的包 VFPEntityFrameworkProvider2),我能够很好地建立连接。我能够从大多数表中加载数据。
当我尝试检索具有大约 240 个字段的特定类型的 DbSet 时出现问题。抛出的异常包含消息:
Compiled code for this line is too long.
据我所知,EF 编写了 SQL select 语句来检索数据,并且此语句太长。当我使用调试器检查局部变量时,我看到一个 SQL 语句,其长度接近 16000 个字符,而 maximum allowed command length for VFP is 8,192 bytes
我不太确定如何解决这个问题,因为我对 EF 还很陌生。我想我可以编辑一些生成的代码,或者编写一些自定义处理程序。也许我可以批量检索字段,然后组合对象。
此外,我相信可以将我的实体分解为类型和子类型;也许如果我这样做,一次只会检索一部分字段。
谁能建议我用什么方式解决这个限制?
添加的注释:
不能选择使用不同的数据库。我坚持使用 FoxPro 和这个特定的架构。但是,我可以自由地改变解决问题的方法。当然,我可以自己写DB访问代码,但是如果能用EF就更好了。
发送到 VFP 的查询实际上看起来像这样:
SELECT
E1.Wn_Ref,
E1.Wn_Surname,
E1.Wn_Forenam,
E1.Wn_Dirctr,
...
E1.Wn_Chqno,
CAST( E1.Wn_Lelval AS n(20,2)) AS Wn_Lelval,
E1.Wn_Dirstpd,
...
E1.Wn_Leavdt,
CAST( E1.Wn_Grsprv AS n(20,2)) AS Wn_Grsprv,
CAST( E1.Wn_Taxprv AS n(20,2)) AS Wn_Taxprv,
E1.Wn_Ovride,
E1.Wn_Nichgpr,
...
E1.Wn_Totabs,
CAST( E1.Wn_Tgrspay AS n(20,2)) AS Wn_Tgrspay,
CAST( E1.Wn_Tottax AS n(20,2)) AS Wn_Tottax,
CAST( E1.Wn_Totpens AS n(20,2)) AS Wn_Totpens,
CAST( E1.Wn_Totsspr AS n(20,2)) AS Wn_Totsspr,
CAST( E1.Wn_Totsmp AS n(20,2)) AS Wn_Totsmp,
CAST( E1.Wn_Totchrt AS n(20,2)) AS Wn_Totchrt,
CAST( E1.Wn_Totcmee AS n(20,2)) AS Wn_Totcmee,
CAST( E1.Wn_Totcmer AS n(20,2)) AS Wn_Totcmer,
CAST( E1.Wn_Tcmeeyr AS n(20,2)) AS Wn_Tcmeeyr,
CAST( E1.Wn_Tcmeryr AS n(20,2)) AS Wn_Tcmeryr,
CAST( E1.Wn_Totpenl AS n(20,2)) AS Wn_Totpenl,
CAST( E1.Wn_Totpay AS n(20,2)) AS Wn_Totpay,
CAST( E1.Wn_Tothol AS n(20,1)) AS Wn_Tothol,
CAST( E1.Wn_Roundbf AS n(20,2)) AS Wn_Roundbf,
E1.Wl_Totsspd,
E1.Wl_Totabs,
CAST( E1.Wl_Tgrspay AS n(20,2)) AS Wl_Tgrspay,
CAST( E1.Wl_Tottax AS n(20,2)) AS Wl_Tottax,
CAST( E1.Wl_Totpens AS n(20,2)) AS Wl_Totpens,
CAST( E1.Wl_Totsspr AS n(20,2)) AS Wl_Totsspr,
CAST( E1.Wl_Totsmp AS n(20,2)) AS Wl_Totsmp,
CAST( E1.Wl_Totchrt AS n(20,2)) AS Wl_Totchrt,
CAST( E1.Wl_Totcmee AS n(20,2)) AS Wl_Totcmee,
CAST( E1.Wl_Totcmer AS n(20,2)) AS Wl_Totcmer,
CAST( E1.Wl_Tcmeeyr AS n(20,2)) AS Wl_Tcmeeyr,
CAST( E1.Wl_Tcmeryr AS n(20,2)) AS Wl_Tcmeryr,
CAST( E1.Wl_Totpenl AS n(20,2)) AS Wl_Totpenl,
CAST( E1.Wl_Totpay AS n(20,2)) AS Wl_Totpay,
CAST( E1.Wl_Tothol AS n(20,1)) AS Wl_Tothol,
CAST( E1.Wl_Txb AS n(20,2)) AS Wl_Txb,
CAST( E1.Wl_Tax AS n(20,2)) AS Wl_Tax,
CAST( E1.Wl_Net AS n(20,2)) AS Wl_Net,
CAST( E1.Wl_Erni AS n(20,2)) AS Wl_Erni,
CAST( E1.Wl_Eeni AS n(20,2)) AS Wl_Eeni,
CAST( E1.Wl_Cnoni AS n(20,2)) AS Wl_Cnoni,
CAST( E1.Wl_Nien AS n(20,2)) AS Wl_Nien,
CAST( E1.Wl_Nieco AS n(20,2)) AS Wl_Nieco,
CAST( E1.Wl_Compee AS n(20,2)) AS Wl_Compee,
CAST( E1.Wl_Comper AS n(20,2)) AS Wl_Comper,
CAST( E1.Wl_Pen AS n(20,2)) AS Wl_Pen,
CAST( E1.Wl_Penbl AS n(20,2)) AS Wl_Penbl,
CAST( E1.Wl_Roundcf AS n(20,2)) AS Wl_Roundcf,
CAST( E1.Wn_Ssp1 AS n(20,2)) AS Wn_Ssp1,
CAST( E1.Wn_Ssp2 AS n(20,2)) AS Wn_Ssp2,
CAST( E1.Wn_Ssp3 AS n(20,2)) AS Wn_Ssp3,
CAST( E1.Wn_Ssp4 AS n(20,2)) AS Wn_Ssp4,
CAST( E1.Wn_Ssp5 AS n(20,2)) AS Wn_Ssp5,
CAST( E1.Wn_Ssp6 AS n(20,2)) AS Wn_Ssp6,
CAST( E1.Wn_Ssp7 AS n(20,2)) AS Wn_Ssp7,
CAST( E1.Wn_Ssp8 AS n(20,2)) AS Wn_Ssp8,
E1.Wn_Ssprate,
...
E1.Wn_Pwxretn
FROM (SELECT
Wname.Wn_Ref,
...
Wname.Wn_Chqno,
CAST( Wname.Wn_Lelval AS n(20,2)) AS Wn_Lelval,
Wname.Wn_Dirstpd,
Wname.Wn_Payfrq,
Wname.Wn_Birth,
Wname.Wn_Startdt,
Wname.Wn_Leavdt,
CAST( Wname.Wn_Grsprv AS n(20,2)) AS Wn_Grsprv,
CAST( Wname.Wn_Taxprv AS n(20,2)) AS Wn_Taxprv,
Wname.Wn_Ovride,
...
Wname.Wn_Totabs,
CAST( Wname.Wn_Tgrspay AS n(20,2)) AS Wn_Tgrspay,
CAST( Wname.Wn_Tottax AS n(20,2)) AS Wn_Tottax,
CAST( Wname.Wn_Totpens AS n(20,2)) AS Wn_Totpens,
CAST( Wname.Wn_Totsspr AS n(20,2)) AS Wn_Totsspr,
CAST( Wname.Wn_Totsmp AS n(20,2)) AS Wn_Totsmp,
CAST( Wname.Wn_Totchrt AS n(20,2)) AS Wn_Totchrt,
CAST( Wname.Wn_Totcmee AS n(20,2)) AS Wn_Totcmee,
CAST( Wname.Wn_Totcmer AS n(20,2)) AS Wn_Totcmer,
CAST( Wname.Wn_Tcmeeyr AS n(20,2)) AS Wn_Tcmeeyr,
CAST( Wname.Wn_Tcmeryr AS n(20,2)) AS Wn_Tcmeryr,
CAST( Wname.Wn_Totpenl AS n(20,2)) AS Wn_Totpenl,
CAST( Wname.Wn_Totpay AS n(20,2)) AS Wn_Totpay,
CAST( Wname.Wn_Tothol AS n(20,1)) AS Wn_Tothol,
CAST( Wname.Wn_Roundbf AS n(20,2)) AS Wn_Roundbf,
Wname.Wl_Totsspd,
Wname.Wl_Totabs,
CAST( Wname.Wl_Tgrspay AS n(20,2)) AS Wl_Tgrspay,
CAST( Wname.Wl_Tottax AS n(20,2)) AS Wl_Tottax,
CAST( Wname.Wl_Totpens AS n(20,2)) AS Wl_Totpens,
CAST( Wname.Wl_Totsspr AS n(20,2)) AS Wl_Totsspr,
CAST( Wname.Wl_Totsmp AS n(20,2)) AS Wl_Totsmp,
CAST( Wname.Wl_Totchrt AS n(20,2)) AS Wl_Totchrt,
CAST( Wname.Wl_Totcmee AS n(20,2)) AS Wl_Totcmee,
CAST( Wname.Wl_Totcmer AS n(20,2)) AS Wl_Totcmer,
CAST( Wname.Wl_Tcmeeyr AS n(20,2)) AS Wl_Tcmeeyr,
CAST( Wname.Wl_Tcmeryr AS n(20,2)) AS Wl_Tcmeryr,
CAST( Wname.Wl_Totpenl AS n(20,2)) AS Wl_Totpenl,
CAST( Wname.Wl_Totpay AS n(20,2)) AS Wl_Totpay,
CAST( Wname.Wl_Tothol AS n(20,1)) AS Wl_Tothol,
CAST( Wname.Wl_Txb AS n(20,2)) AS Wl_Txb,
CAST( Wname.Wl_Tax AS n(20,2)) AS Wl_Tax,
CAST( Wname.Wl_Net AS n(20,2)) AS Wl_Net,
CAST( Wname.Wl_Erni AS n(20,2)) AS Wl_Erni,
CAST( Wname.Wl_Eeni AS n(20,2)) AS Wl_Eeni,
CAST( Wname.Wl_Cnoni AS n(20,2)) AS Wl_Cnoni,
CAST( Wname.Wl_Nien AS n(20,2)) AS Wl_Nien,
CAST( Wname.Wl_Nieco AS n(20,2)) AS Wl_Nieco,
CAST( Wname.Wl_Compee AS n(20,2)) AS Wl_Compee,
CAST( Wname.Wl_Comper AS n(20,2)) AS Wl_Comper,
CAST( Wname.Wl_Pen AS n(20,2)) AS Wl_Pen,
CAST( Wname.Wl_Penbl AS n(20,2)) AS Wl_Penbl,
CAST( Wname.Wl_Roundcf AS n(20,2)) AS Wl_Roundcf,
CAST( Wname.Wn_Ssp1 AS n(20,2)) AS Wn_Ssp1,
CAST( Wname.Wn_Ssp2 AS n(20,2)) AS Wn_Ssp2,
CAST( Wname.Wn_Ssp3 AS n(20,2)) AS Wn_Ssp3,
CAST( Wname.Wn_Ssp4 AS n(20,2)) AS Wn_Ssp4,
CAST( Wname.Wn_Ssp5 AS n(20,2)) AS Wn_Ssp5,
CAST( Wname.Wn_Ssp6 AS n(20,2)) AS Wn_Ssp6,
CAST( Wname.Wn_Ssp7 AS n(20,2)) AS Wn_Ssp7,
CAST( Wname.Wn_Ssp8 AS n(20,2)) AS Wn_Ssp8,
Wname.Wn_Ssprate,
...
FROM Wname Wname) E1
虽然您可能无法选择数据库,但您可以选择 Entity Framework 吗?我发现使用 Dapper 更适合这种情况,并且可以让您对查询进行低级控制。
sql 语句可能超过 8000+ 限制的原因有很多。作为 VFP EF Provider 的作者,鉴于 VFP 和 Entity Framework 之间的各种限制,我已经尝试尽可能减少 sql 语句。但是 240 个字段没有太多回旋余地。就我个人而言,我会接受 Cetin Basoz 的建议,即通过创建多个 类 来将其视为多个 table,这些 类 代表 table 到 trim 的一部分 sql 语句。或者,您可以使用 LINQ Select 操作只提供字段的子集。那应该为您减少语句,使其不超过 8000+ 限制。
(取消对你的 linq 语句的假设,因为它没有显示......) 如果您确实需要所有列,那么您可能想尝试在仅获取主键的查询和使用主键 return 所有字段的查询之间分解查询。这可能对你有用。
我自己的回答:在处理了一段时间后,我发现 tables 以只读方式添加到 EDMX 模型中。这意味着它是 selecting 来自 select 语句,这是多余的,并且膨胀了 select 语句的大小。当我手动编辑 EDMX 文件并强制其将 table 视为可读写时,问题消失了。
此外,在 Tom 的建议下,我开始更好地欣赏代码优先方法。我完全取消了 EDMX 模型。我发现这更容易管理,因为我通过模型的 class 属性上的属性控制每个字段的处理方式。使用代码优先,我对上下文 classes 的自定义不可能被覆盖;这对我来说是完美的,因为我需要自定义构造函数并覆盖 SaveChanges 和其他方法。