2012-03-27 52 views
2

我正在使用DB2提供程序来访问AiX服务器上的数据库。这是我用来返回匿名类型的LINQ语句。使用Take()与匿名类型(DB2提供程序)

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

回答

1

这种情况的解决方法是做分组和过滤存储器和获取数据的更大量的背面从源

1

如果问题确实是由于您使用匿名类型引起的,您可以改为创建一个指定类型。

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语句生成之前发生的)。

+0

它definently是基团通过然后取()。我能够把这个小组取出来,将结果存储在内存中,然后分组。我可以尽力做到这一点,但它并不优雅。思考? – 2012-03-27 17:32:10

+0

@IsaacLevin:如果您创建一个命名类来表示您正在分组的对象,并使用它来代替匿名类型,会发生什么? – StriplingWarrior 2012-03-27 18:11:00

+0

@StriplingWarrier,你能举个例子吗,我没跟着。 – 2012-03-27 20:19:00

0

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

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

拿出来看看它是否有效。

+0

解决了同样的问题。 – 2012-03-27 17:33:18