开发者

Linq object Enumeration

I'm brand new to linq. I'm sure that I'm missing something due to inexperience.

the problem: I am using linq to query objects and return enumerable Acct o开发者_如何转开发bjects where o.Diff!=0

if I try to enumerate the results I get the error unable to cast object of type System.Collections.Generic.KeyValuePair '2[Acct]' to type 'Acct'.

the question: how can i return enumerable Acct objects from the Linq query?

Thanks in advance!

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();
  }
}


The problem is that as you iterate over your dictionary, you are casting each item as an Acct, when in fact, each of the items in your Dictionary is a KeyValuePair. Try something like:

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


When you iterate over acct, each item is a key/value pair from the dictionary. Assuming the Acct object is the value in each pair, you would get all of the nonzero accounts like this:

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


As others have said, it sounds like you want to be iterating over the values, not the key/value pairs.

That means you could use a query like this:

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

but personally I wouldn't bother using a query expression in this case. I'd just use the extension methods:

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

Now, in terms of the return type, I strongly suspect you want to return IEnumerable<AcctSum> rather than IEnumerator or IEnumerator<T>. So you might want:

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

or you might want to "materialize" the query - get all the results in one go, and return those (rather than returning a query which can be iterated over lazily). For example:

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

In particular, by materializing the query you're allowing callers to modify acct while they're iterating over these results - if they try to do so while they're iterating over the raw query, they'll get an exception.

You'll also need to change your AcctSum class, because ArrayList isn't a generic type in .NET. Did you mean to use List<T>?


Well, it's b/c acct is a dictionary (which is an IEnumerable<KeyValuePair>, iirc, under the hood. Change your source from acct to acct.Values


First, the return type should be IEnumerator, not IEnumerable. Secondly, acct contains a collection of key value pairs, so you have to run the query on the key value (in this case)

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜