none
What is wrong with my LINQ query? RRS feed

  • Question

  • I keep getting "Index was outside the bounds of the array" error. 

                    decimal cnt = (from positions in myTable.AsEnumerable()
                                   where (positions.Field<int>("Id") == id)
                                      && (positions["Age"] != DBNull.Value)
                                   select positions.Field<decimal>("Age")).DefaultIfEmpty(0).Count();

    Is it not able to CAST "Id" to int or "Age" to decimal? Or is it something else.

    Thanks.

    • Moved by Kristin Xie Monday, January 25, 2016 8:07 AM
    Friday, January 22, 2016 5:31 PM

Answers

  • You wrote:

    decimal cnt = (blah blah blah).Count();


    The result of .Count() is int, not decimal.  So that's the first thing that's weird.  An int fits in a decimal without loss of precision, so it gets converted without warning according to Decimal Implicit Conversion.

    I also don't understand why you would use DefaultIfEmpty in this case.  It means that you are expecting a collection of ages like { 1.2, 3.4, 5.6 } (which has 3 items) and you are turning the empty collection {} (which has 0 items) into this collection { 0.0M } which has 1 item.  The .Count() of which will be 1 instead of 0.  That's strange.

    Also, if your goal is just to count the records that have Id==id and also have an "Age" field, then there's no need to then continue on to select the age field, just to count them.  You don't have to know a thing's age to count it.  So that's weird too.

    Count actually can take a predicate directly.  So you could have done:

    int cnt = myTable
        .AsEnumerable()
        .Count( positions => (positions.Field<int>("Id") == id) && (positions["Age"] != DBNull.Value) );

    I also don't know what type myTable is.  Is it necessary to use AsEnumerable() on it?  I'm not sure what you're starting with.

    I agree with Michael Taylor that myTable.Rows.OfType<DataRow>() may be necessary if that's your situation.

    But finally, I don't see an array.  So... I'm honestly not sure how you got the indexing problem at all.


    Friday, January 22, 2016 7:23 PM

All replies

  • If myTable is a DataTable then you're going to have issues as DataTable doesn't implement IQueryable and isn't generic. In general you'll need to write your query something like this.

    myTable.Rows.OfType<DataRow>()

    You'll also run into issues if the columns you're referencing (Id and Age) don't actually exist in the table. Yet another issue can be caused by the field not being the type you specified. For SQL it will only allow a cast to the correct type and won't (generally) do any coercion (i.e. upcasting an int to a double).

    Given your error I'm going to guess that either Positions isn't the actual rows like you thought or that the field names don't exist in the table.  Setting a breakpoint on this code and viewing the table contents will clarify what is going on.

    Michael Taylor
    http://blogs.msmvps.com/p3net

    Friday, January 22, 2016 6:06 PM
  • You wrote:

    decimal cnt = (blah blah blah).Count();


    The result of .Count() is int, not decimal.  So that's the first thing that's weird.  An int fits in a decimal without loss of precision, so it gets converted without warning according to Decimal Implicit Conversion.

    I also don't understand why you would use DefaultIfEmpty in this case.  It means that you are expecting a collection of ages like { 1.2, 3.4, 5.6 } (which has 3 items) and you are turning the empty collection {} (which has 0 items) into this collection { 0.0M } which has 1 item.  The .Count() of which will be 1 instead of 0.  That's strange.

    Also, if your goal is just to count the records that have Id==id and also have an "Age" field, then there's no need to then continue on to select the age field, just to count them.  You don't have to know a thing's age to count it.  So that's weird too.

    Count actually can take a predicate directly.  So you could have done:

    int cnt = myTable
        .AsEnumerable()
        .Count( positions => (positions.Field<int>("Id") == id) && (positions["Age"] != DBNull.Value) );

    I also don't know what type myTable is.  Is it necessary to use AsEnumerable() on it?  I'm not sure what you're starting with.

    I agree with Michael Taylor that myTable.Rows.OfType<DataRow>() may be necessary if that's your situation.

    But finally, I don't see an array.  So... I'm honestly not sure how you got the indexing problem at all.


    Friday, January 22, 2016 7:23 PM
  • Thanks guys - will change by code as suggested.
    Monday, January 25, 2016 5:24 AM
  • Hi JayShah203,

    This forum is about the C# programming language, IDE, libraries, samples, and tools, as your issue is more related to the LINQ query, we help you move it to the LINQ to SQL forum for better support.

    Thank you for your understanding.

    Best Regards,

    Albert Zhang


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, January 25, 2016 8:01 AM
  • Hi JayShah203,

    I use your code snippet and try to reproduce the issue on my side, It woks fine. And my development environment is: visual studio Enterprise 2015, .net framework 4.6. Could you please provide a bit more information about the myTable. I would try to reproduce the issue and solve it better.

    Best regards,

    Cole Wu

    Wednesday, January 27, 2016 7:26 AM
    Moderator