首先,关于环境的一些背景信息......
有两台机器:Windows“客户端”和Linux“服务器”。
- Windows 2008 R2 x64 • IIS 7.5 • NET 3.5 • SharePoint 2010 • Visual Studio 2010 • IBM DB2 .NET 数据提供程序运行时版本 v4.0.30319,驱动程序版本 9.7.4.4。
- RedHat Linux、IBM DB2 数据库版本 9.5.3*。
* IBM 网站上推荐的解决方案是将客户端升级到 9.7 FP5。我已经尝试过了,甚至升级到了 10 版,但仍然遇到同样的错误。如果本文的作者指的是需要升级的服务器上运行的实际数据库版本,那么这会带来问题,因为目前这不是我的客户可以接受的解决方案。
我并不死心于使用 LINQ-to-Entities,并且会欢迎兼容的替代方案,前提是我不需要重写当前依赖它的大量现有代码。
现在,关于这个问题……</p>
下面是我试图执行的代码。注意查询中使用的 caseid 参数。
public List<JqueryAutocompleteEntity> Cases(string caseid)
{
var query = (from c in context.ASSET_T
where c.CA_ID_AGCY.StartsWith(caseid.Trim().ToUpper())
select new JqueryAutocompleteEntity
{
id = c.CA_ID_AGCY.Trim(),
label = c.CA_ID_AGCY.Trim(),
value = c.CA_ID_AGCY.Trim()
}).Distinct().Take(10);
return query.ToList();
}
当上面的代码在运行时执行时,会抛出以下异常:
执行命令定义时发生错误。有关详细信息,请参阅内部异常。IBM.Data.DB2.DB2Exception: ERROR [42815] [IBM][DB2/LINUXX8664] SQL0171N 例程“SYSIBM.STRIP”的位置“string-expr”中的参数的数据类型、长度或参数值不正确. 参数名称:“”。在 IBM.Data.DB2.DB2Command.ExecuteReaderObject(CommandBehavior 行为,String 方法,DB2CursorType reqCursorType,Boolean abortOnOptValueChg,Boolean skipDeleted,Boolean isResultSet,Int32 maxRows,Boolean skipInitialValidation)在 IBM.Data.DB2.DB2Command.ExecuteReaderObject(CommandBehavior 行为,String方法)在 IBM.Data.DB2.DB2Command.ExecuteDbDataReader(CommandBehavior 行为)在 System.Data 的 IBM.Data.DB2.DB2Command.ExecuteReader(CommandBehavior 行为)。
这是 LINQ-to-Entities 生成的 SQL 语句,它被传递给 .NET DB2 驱动程序,以便在 DB2 数据库中的 Linux 服务器上执行。
SELECT CAST(1 AS int) AS C1, STRIP(Extent1.CA_ID_AGCY,BOTH) AS C2, STRIP(Extent1.CA_ID_AGCY,BOTH) AS C3, STRIP(Extent1.CA_ID_AGCY,BOTH) AS C4 从 ASSET_T 作为 Extent1 WHERE (LOCATE( UPPER(STRIP(@p_linq _1 ,BOTH)), Extent1.CA_ID_AGCY)) = CAST(1 AS int)
如您所见,似乎在生成最终 SQL 语句时使用了参数/变量的名称,而不是用实际值替换它。此外,将值硬编码到我的 LINQ 查询中实际上可以正常工作。
c.CA_ID_AGCY.StartsWith(“test”.Trim().ToUpper()) <= 这行得通!!!
我已经尝试在 LINQ 查询的第一部分使用 .AsEnumerable() 扩展名,因此我可以将所有数据加载到内存中,然后使用我的参数执行过滤器,但这种方法显然不起作用,因为结果集是 WAY太大(即数百万条记录)。它最终会杀死服务器的 CPU 并最大化 RAM。通过直接对数据库执行查询并使用 foreach 循环来填充 JQueryAutocompleteEntity 对象的集合,我显然可以使用简单的“经过验证的”DataReader/DataTable 方法来完成我所需要的,但我更喜欢使用更优雅的解决方案像 LINQ-to-Entities 一样,也避免浪费额外的执行时间来填充 foreach 循环中的列表。
我发现这一切令人不安的是,对参数化查询的支持似乎是一个如此明显的特性。我的意思是在用任何语言编码时,你多久使用一次常量而不是变量?
我认为 Scott Guthrie 关于他的自定义动态查询库的博客文章似乎为我的问题提供了一种解决方法,但并不完全存在。
任何解决此问题的帮助(无需升级 .NET Framework 或 DB2)将不胜感激。
谢谢!