C# .NET-与Visual FoxPro一起使用实体框架-错误“;此行的编译代码太长。”;

C# .NET-与Visual FoxPro一起使用实体框架-错误“;此行的编译代码太长。”;,c#,.net,entity-framework-6,visual-foxpro,foxpro,C#,.net,Entity Framework 6,Visual Foxpro,Foxpro,我正在尝试将EntityFramework6(EF)与Visual FoxPro数据库一起使用(使用NuGet提供的VFPEntityFrameworkProvider2包),我能够使连接正常。我能够从大多数表加载数据 当我试图检索某个类型的DbSet时,会出现问题,该DbSet大约有240个字段。引发的异常包含以下消息: 此行的编译代码太长 据我所知,EF编写了SQLSELECT语句来检索数据,但该语句太长。当我使用调试器检查局部变量时,我看到一条SQL语句,其长度接近16000个字符,而

我正在尝试将EntityFramework6(EF)与Visual FoxPro数据库一起使用(使用NuGet提供的VFPEntityFrameworkProvider2包),我能够使连接正常。我能够从大多数表加载数据

当我试图检索某个类型的DbSet时,会出现问题,该DbSet大约有240个字段。引发的异常包含以下消息:

此行的编译代码太长

据我所知,EF编写了SQLSELECT语句来检索数据,但该语句太长。当我使用调试器检查局部变量时,我看到一条SQL语句,其长度接近16000个字符,而

我不太确定如何解决这个问题,因为我对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

虽然您可能无法选择数据库,但您是否可以选择实体框架?我发现在这种情况下,使用Dapper更适合,并且可以让您对查询进行低级控制。

sql语句可能超过8000+限制的原因有很多。作为VFP-EF提供者的作者,我已经尝试在VFP和实体框架之间存在各种约束的情况下尽可能减少sql语句。但240个字段没有多少回旋余地。就个人而言,我赞同Cetin Basoz的建议,即通过创建表示表的一部分的多个类来减少sql语句,从而将其视为多个表。或者,您可以使用LINQ Select操作提供字段的子集。这将减少您的声明,使其不超过8000+的限制

(由于没有显示linq语句,因此偏离了linq语句的假设…)
如果您真的需要所有列,那么您可能希望尝试在仅获取主键的查询和使用主键返回所有字段的查询之间拆分查询。这可能对您有用。

我自己的回答:在使用了一段时间后,我发现表格以只读方式添加到EDMX模型中。这意味着它是从一个多余的select语句中选择的,并且使select语句的大小膨胀。当我手动编辑EDMX文件并强制它将表视为读写时,问题消失了


此外,在Tom的建议下,我越来越欣赏代码优先的方法。我完全取消了EDMX模型。我发现这更容易管理,因为我通过模型类属性上的属性来控制如何处理每个字段。首先使用代码,我对上下文类的定制不会被覆盖;这对我来说是完美的,因为我需要自定义构造函数并覆盖SaveChanges和其他方法。

显然这是一个问题,没有EF你也无法查询。用另一个数据库替换Foxpro?这通常不是那么简单。在很多情况下,人们都需要与使用它的第三方应用程序进行对话,或者是他们自己的应用程序进行了几十年的投资,却没有在另一个后端花费六便士。240个字段模式是否超过8K?要实现这一点,每个字段名应该有超过32个字符,不是吗?EF支持直接使用SQL。我可能会将其视为一个水平分割的多个表,其中每个部分都有相同的主键(1对1)。你好,Tom,非常感谢您的回复和建议。对您来说,一个有些不相关的问题是:组件的许可证是否允许它用于商业项目?是的,提供程序可以用于商业项目。它使用LINQ运行得非常好。谢谢你的想法。在VFP中,如果你将关键字尽可能地截短到前4个字符,你可以节省几个字符,并且去掉换行符和多余的空格,比如转换后的空格。这些都不符合VFP的字符限制。谢谢你的想法。我将研究它是否可以作为我们项目的解决方案。