使用带有匿名类型的Take()(DB2 Provider)

时间:2012-03-27 13:40:31

标签: c# linq-to-sql db2 anonymous-types

我正在使用DB2提供程序来命中AiX Server上的数据库。这是我正在使用的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();

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

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元素?

3 个答案:

答案 0 :(得分:1)

如果问题确实来自您使用匿名类型,则可以改为创建命名类型。

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

然而,该错误消息有点神秘,我不确定这与匿名类型有什么关系。我建议你逐步削减你的查询,直到你有一个最低限度再现错误。通过这种方式,您可以更加确定导致问题的原因。

您可能需要考虑在OrderBy之前添加Take,因为某些提供商要求订购一组数据才能执行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语句之前发生的。)

答案 1 :(得分:1)

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

答案 2 :(得分:0)

可能是这部分和其他对不在查询中的对象的引用。

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

拿出来看看它是否有效。