8

I have a linq query that returns a list of MyObject. I'd like to add a property to MyObject called TheIndex and that contains the ordinate of the item in the sequence.

In other words, I need something like this:

var TheResult = from d in MyDataContext
                where.....
                select new MyObject
                {
                   Property1 = d.whatever,

                   TheIndex = ?

                 }

The query returns a list of MyObject and I'd like each item in the list to contain the index as one of its property.

Thanks.

frenchie
  • 51,731
  • 109
  • 304
  • 510
  • Possible duplicate of [How do you add an index field to Linq results](http://stackoverflow.com/questions/269058/how-do-you-add-an-index-field-to-linq-results) – Michael Freidgeim Jul 13 '16 at 03:26

1 Answers1

17

Once you get away from the query syntax, you'll find a Select overload that gives you the index you're looking for.

var result = MyDataContext
   .Where(d => d.Prop == "A")
   .AsEnumerable()
   .Select((d, i) => 
      new MyObject() {
         Property1 = d.whatever,
         TheIndex = i
    });
FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • just before the select statement, there's an error on the parenthesis: a query body must end with a select clause or a group clause. – frenchie Feb 15 '11 at 02:43
  • 1
    Yeah - I fixed that. Just ditch the query syntax altogether and go with method syntax, like I have now. – Adam Rackis Feb 15 '11 at 02:45
  • I'm not getting any intellisense when I convert to method syntax: am I doing it wrong? In query syntax I had var Output = from d in MyDC.Table1 where d.UserID == TheUserId where d.Date == TheDate.Date select new Model{...}. – frenchie Feb 15 '11 at 03:20
  • I got it fixed syntax-wise but I get an error at runtime: Unsupported overload used for query operator – frenchie Feb 15 '11 at 03:38
  • What's the whole error? Might also be time to fork this into a new question. Post the link here if you do. – Adam Rackis Feb 15 '11 at 03:44
  • 1
    The overload Adam mentions is only implemented in LINQ to Objects, not in LINQ to SQL. Easiest workaround is probably to use AsEnumerable: `.Select(d => d.whatever).AsEnumerable().Select((w, i) => new MyObject { Property1 = w, TheIndex = i })`. The AsEnumerable forces the second Select to be processed using LINQ to Objects. (You could omit the first Select and do everything after the AsEnumerable, but this would download all database columns instead of just the 'whatever' column, so splitting into two Selects is more efficient.) – itowlson Feb 15 '11 at 03:44
  • Thanks, @itowlson My answer is updated with the AsEnumerable(). It's obvious now that I see it - it wouldn't make sense for that overload to be parsed into a SQL command - at least not naturally – Adam Rackis Feb 15 '11 at 03:54
  • ok, wonderful! I have no clue how this all works, but it works! Query syntax just seems more simple. Thank you for your help. – frenchie Feb 15 '11 at 03:59
  • Query syntax really shines more when you start doing Joins. For relatively simple queries like this, method syntax is to me much smoother, but it's a matter of opinion. Before you really get going with LINQ, I would really recommend you get acquainted with how LINQ does deferred query execution (which is how itowlson's addition works). Without understanding that, you run the risk of really shooting yourself in the foot (for example, iterating a query 5 times and not realizing that you're running 5 DB round trips) – Adam Rackis Feb 15 '11 at 04:04
  • Why not just put it in a list 'ToList()' and use that index? – Magnus Feb 15 '11 at 09:04