将Take()与Anonymous类型(DB2 Provider)一起使用

本文关键字:Provider 一起 DB2 Anonymous Take 类型 | 更新日期: 2023-09-27 18:29:04

我正在使用DB2提供程序访问AiX服务器上的数据库。这是我正在使用的LINQ语句,它返回一个匿名类型。

var docs = (from a in WIP
            where (!dtFrom.HasValue && !dtTo.HasValue) || (a.QBE_DT.Value >= dtFrom.Value && a.QBE_DT.Value <= dtTo.Value) && a.STATUSCODE != "X" && a.KEY1 != "CABS" && a.KEY1 != "BPI"
            group a by new
            {
                a.BATCH_ID,
                a.POLICY_NUM,
                a.QBE_DT
            } into grp
            select new
            {
                BatchId = grp.Key.BATCH_ID.Trim(),
                BatchGroup = grp
            }).ToList();

由此返回的结果导致提供程序超时,抛出的进程由于中断错误而被取消。我的想法是,如果我"拿走"记录集的一个子集,这个问题就会消失。我的问题是,我不能简单地在ToList()之前添加Take(100),因为它抛出:

SQL0418N A statement contains a use of an untyped parameter marker, the DEFAULT keyword, or a null value that is not valid. SQLSTATE=42610

我希望我能够看到生成的SQL,以确保它是正确的语法,但我不知道在这种情况下该怎么做。有没有一种优雅的方法可以从上面的LINQ语句中获得第一个X元素?

将Take()与Anonymous类型(DB2 Provider)一起使用

如果问题确实是由使用匿名类型引起的,那么您可以创建一个命名类型。

public class BatchKey
{
    public int BatchId {get;set;}
    ...
}
...
        group a by new BatchKey
        {
            BatchId = a.BATCH_ID,
            ...

然而,这个错误消息有点神秘,我不确定这是否与匿名类型有关。我建议你一个接一个地减少你的查询,直到你有一个能重现错误的最低限度。这样你就可以更加确定是什么导致了这个问题。

您可能需要考虑在Take之前添加OrderBy,因为有些提供程序要求对一组数据进行排序才能执行Take。您可能还想评估查询之外的内容:

IQueryable<WIP> wips = WIP.Where(a => a.STATUSCODE != "X" && a.KEY1 != "CABS" && a.KEY1 != "BPI");
if (dtFrom.HasValue) {
   wips = docs.Where(a => a.QBE_DT.Value >= dtFrom.Value);
}
if (dtTo.HasValue) {
   wips = docs.Where(a => a.QBE_DT.Value <= dtTo.Value);
}
var docs = from a in wips
           group a by ...

我相信您应该能够设置LINQPad来使用DB2提供程序,并查看正在生成的SQL语句。(但是这个错误看起来是在生成SQL语句之前发生的)。

解决方法是在内存中进行分组和过滤,并从源中获取更多数据

这可能是查询中没有的这一部分以及对对象的其他引用。

(!dtFrom.HasValue && !dtTo.HasValue)

把它拿出来看看是否有效。