8

I don't think I can actually add a field (column) to an existing IEnumerable. But what I want is a new IEnumerable that is derived from an existing IEnumerable with a calculated field. The pseudocode in WebMatrix using Web Pages looks like:

var db = Database.Open("LOS");
var ie = db.Query(sqlAssignments);

// make a new ie2 that has an extra field
// ??? ie2 <=== ie with new field c = ie.a + ie.b

var grid = new WebGrid( ie2, extra parameters );

I know how to do this looping through all the rows in ie. But I'm hoping there's something more elegant.

Knox
  • 2,909
  • 11
  • 37
  • 65
  • 2
    IEnumerable simply signifies an enumerable type, i.e. a consumer can enumerate through it's constituent items. It has no concept of 'fields' or 'columns'. – Adam Ralph Mar 17 '11 at 11:45
  • 4
    @Adam - yet I think more people are likely to understand *that* title than, for example: "Use a projection to create a new sequence based on an old sequence, but with additional members"... – Marc Gravell Mar 17 '11 at 11:48

5 Answers5

6

How about:

var ie2 = ie.Select(x => new { x.Foo, x.Bar, Sum = x.Abc + x.Def });
var grid = new WebGrid(ie2);
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • this works great, but bizarrely has led to a new problem where the WebGrid no longer automatically sorts :( . I decided to make it a new question. – Knox Mar 17 '11 at 12:35
  • @Knox - just use ie2.ToList() – Marc Gravell Mar 17 '11 at 12:44
  • I tried ToList, but it still didn't sort. Rather than morph this question into the new question, i asked a new question. http://stackoverflow.com/questions/5339335/add-a-column-to-an-ienumerable-in-c-such-that-it-works-with-webgrid – Knox Mar 17 '11 at 13:01
  • 3
    that's kind of a pain: what if you have like 20 columns or more? – Arman Bimatov Nov 27 '13 at 15:55
4

You can do this using Select. Try this:

ie2 = ie.Select( e => new { IE = e, NewParam =  e.X+e.Y });
Øyvind Bråthen
  • 59,338
  • 27
  • 124
  • 151
  • 1
    The one comment I have about this is that most data-binding only looks one level down; you usually need to flatten the properties of `e`, otherwise you'll just have a column named `e` with `e.ToString()` as the values. – Marc Gravell Mar 17 '11 at 11:46
  • If that is the case, you will have to flatten as your answer depicts. If it only looks down one level, let's hope the number of properties on `e` is manageable :) – Øyvind Bråthen Mar 17 '11 at 11:48
  • I didn't get this to immediately work, and decided to flatten it. Fortunately, there are only about 10 properties on e. – Knox Mar 17 '11 at 12:35
3
ie2 = ie.Select(v => new {v.a, v.b, c = v.a + v.b});
Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
2

Using Linq!

var newIe = from item in ie
            select new {item.NewField, item.OldFiedl1 etc... }

Also, probably best (if you intend to use outside this method) to make that anonymous type named.

Massif
  • 4,327
  • 23
  • 25
2

First of all, the IEnumerable is probably a list of something - an object. That is the object you can extend.

You can probably do something like this:

var ie = db.Query( ... );
var ie2 = ie.Select(i => new MyIe2Object {
   Prop1 = i.Prop1,
   NewProp = i.Prop1 + i.Prop2
});
Mikael Östberg
  • 16,982
  • 6
  • 61
  • 79