2011-01-11 118 views
0

我是linq的全新品牌。由于缺乏经验,我相信我错过了一些东西。Linq物体枚举

问题: 我使用LINQ查询对象,并返回枚举科目对象where o.Diff!=0

如果我试图枚举结果我得到的错误unable to cast object of type System.Collections.Generic.KeyValuePair '2[Acct]' to type 'Acct'

问题: 如何从Linq查询返回可枚举的Acct对象?

在此先感谢!

public class AcctSum 
{ 
    string ID; 
    Decimal Amt1; 
    Decimal Amt2; 
    Decimal Diff; 
    ArrayList<AcctDet> lines; 
} 

public class AcctInfo 
{ 
    Dictionary<string,AcctSum> acct 

    //code that adds the data... 
    public iEnumerable Discrepancies() 
    { 
    var results = (from Acct a in acct 
        where a.Diff != 0 
        select a).AsEnumerable<Acct>(); 
    foreach (var result in results)//at runtime this generates an error 

    { 
    }          
    return results.GetEnumerator(); 
    } 
} 
+0

您正在交换使用Acct和AcctSum。这看起来不正确。如果Acct是枚举,则不能将其从一个转换为另一个。 – Schultz9999

+0

首先将'from'中的'Acct'改成一个不是类型名称的变量名称,比如'variable1',然后将'AsEnumerable ()'改为'AsEnumerable ()',最后将'in acct'改为'在acct.Values' –

回答

0

正如其他人所说,这听起来像你想被遍历值,而不是键/值对。

这意味着你可以使用这样的查询:

var results = from acctSum value in acct.Values 
       where acctSum.Diff != 0 
       select acctSum; 

但我个人不会在这种情况下使用查询表达式麻烦。我只是使用扩展方法:现在

var results = acct.Values.Where(acctSum => acctSum.Diff != 0); 

,在返回类型而言,我强烈怀疑你想回到IEnumerable<AcctSum>而非IEnumeratorIEnumerator<T>。所以,你可能想:

public IEnumerable<AcctSum> Discrepancies() 
{ 
    return acct.Values.Where(acctSum => acctSum.Diff != 0); 
} 

,或者你可能要“兑现”查询 - 获得所有结果一气呵成,并返回那些(而不是返回可以懒洋洋地遍历一个查询)。例如:

public IEnumerable<AcctSum> Discrepancies() 
{ 
    return acct.Values.Where(acctSum => acctSum.Diff != 0).ToList(); 
} 

特别是,通过物化你允许呼叫者修改acct当他们遍历这些结果查询 - 如果他们试图这样做,当他们遍历原始查询,他们会得到一个例外。

您还需要更改AcctSum类,因为ArrayList不是.NET中的泛型类型。你的意思是使用List<T>

+0

我将切换ArrayList到List,我在另一个示例中看到它。我正在尝试这个,谢谢! – kes

+0

最后一个例子,.ToList(),正是我想要的;尽管如此,整件事仍然感觉像是一个魔术。 我想现在是时候采取的眼罩和学习新的范例:) – kes

0

嗯,这是B/C ACCT是一本字典(这是一个IEnumerable <KeyValuePair>,IIRC,引擎盖下。从ACCT更改源acct.Values

1

当你遍历acct ,每个项目是字典中的键/值对假设Acct对象每对中的值,你会得到所有非零账户是这样的:

from a in acct.Values 
where a.Diff != 0 
select a 
3

的问题是,当你它在你的字典上进行计算,你正在将每个项目转换为一个Acct,实际上,你的Dictionary中的每个项目都是一个KeyValuePair。尝试类似:

from KeyValuePair<string,AcctSum> acctKVP in acct // assuming acct is of type Dictionary<string,AcctSum> 
where acctKvp.Value.Diff != 0 
0

首先,返回类型应该是IEnumerator,而不是IEnumerable。 其次,ACCT包含键值对的集合,所以你需要运行关键数值查询(在这种情况下)

void Main() 
{ 
    var acctInfo = new AcctInfo(); 
    acctInfo.Discrepancies(); 

} 
public class AcctSum 
{ 

    string ID; 
    Decimal Amt1; 
    Decimal Amt2; 
    public Decimal Diff; 
    ArrayList lines; 
} 

public class AcctInfo 
{ 
    public IEnumerator Discrepancies() 
    { 
     var acct = new Dictionary<int, AcctSum> 
         {{1, new AcctSum() {Diff = 0.0M}}, {2, new AcctSum() {Diff = 1.0M}}}; 

     var results = (from AcctSum a in acct.Values where a.Diff != 0 select a).AsEnumerable(); 

     foreach (var result in results)//at runtime this generates an error 
     { 

     } 
     return results.GetEnumerator(); 
    } 
} 
+0

其实,我会返回'IEnumerable '而不是'IEnumerator'。从除了实现“IEnumerable”或“IEnumerable”的GetEnumerator方法以外的任何其他方法返回迭代器非常罕见。 –

+0

与我一样,但是当他返回GetEnumerator()时,我认为这是故意的。无论哪种方式,东西不得不改变:) – Rob

+0

是啊,我搞砸了。我试图实现,以便我可以做foreach和/或将其返回给datagrid绑定。是的,对于绑定我需要调整变量的属性:) – kes