2

I'm newbie to c# and i have problem trying to access IList after i assign it to the query. Here is my code:

System.Collections.IList Invoices =
     (from p in entities.InvoiceCards
      where (p.CustomerCard.ID == CustomerID)
      select new
      {
         InvoiceID = p.ID,
         InvoiceDatetime = p.DateTime,
         InvoiceTotal = (decimal) p.InvoiceTotal,
      }).ToList();

// update the grid
invoiceCardDataGridView.DataSource = Invoices;

----------- Here the compiler is complaining about object c? how can I access the objects in the IList without executing the query again? I need to use IList to use as a datasource. what is a better way? Please include the code

foreach (var c in Invoices)
    InvoiceTotal += (decimal)c.InvoiceTotal;
Rex M
  • 142,167
  • 33
  • 283
  • 313
B Masri
  • 33
  • 4
  • possible duplicate of [Accessing C# Anonymous Type Objects](http://stackoverflow.com/questions/713521/accessing-c-sharp-anonymous-type-objects) – nawfal Jun 28 '14 at 07:55

4 Answers4

1

Your problem that you are using anonymous type in your query. So when you get an IList of this anonymous type and assign to a datasource, by default you will loose its type.

When you want to retrieve it from the DataSource in another part of your code you have to cast it with the appropriate type. Since the anonymous type is generated by the compiler you will not be able to cast it.

A solution is to create the class that contain the type if doesn't exist already.

public class InvoicePart
{
   public int InvoiceID {get; set}
   public DateTime InvoiceDatetime {get; set}
   public decimal InvoiceTotal {get; set}
}

Now you can modify your query to get a typed List

List<InvoicePart> Invoices =
     (from p in entities.InvoiceCards
      where (p.CustomerCard.ID == CustomerID)
      select new InvoicePart
      {
         InvoiceID = p.ID,
         InvoiceDatetime = p.DateTime,
         InvoiceTotal = (decimal) p.InvoiceTotal,
      }).ToList();

// update the grid
invoiceCardDataGridView.DataSource = Invoices;

and when you will get your data you will cast it to a List

List<InvoicePart> Invoices = (List<InvoicePart>)invoiceCardDataGridView.DataSource;

foreach (InvoicePart c in Invoices)
{
    invoiceTotal += c.InvoiceTotal;
}
Zied
  • 1,696
  • 12
  • 20
  • Note this key sentence: "I need to use `IList` to use as a datasource." I read that as a strongly typed version of `IList` not being an option (and note that `IList` is not an `IList`). – jason Oct 31 '10 at 14:04
  • I noted that and I noted that he's a newbie to c#. So I tried to explain an alternative to using the IList – Zied Oct 31 '10 at 16:39
0

If the list contains anonymous types and the foreach loop is in another method than the first block of code you cannot use it that way.

Please have a look to this post that maybe could help in your case.

Community
  • 1
  • 1
Lorenzo
  • 29,081
  • 49
  • 125
  • 222
0

If you absolutely have to use IList then you are better of defining an explicit type rather than using an anonymous type. Then you'll have to cast the elements of the IList to your explicit type when you need to work with them.

jason
  • 236,483
  • 35
  • 423
  • 525
0

Zied has the right idea about solving this issue. Note, however, that binding to a List<T> is not bidierctional (changes to the list will not reflect in the grid). For that you need to use a BindingSource:

List<InvoicePart> Invoices =
     (from p in entities.InvoiceCards
      where (p.CustomerCard.ID == CustomerID)
      select ...

// update the grid
var bs = new BindingSource();
bs.DataSource = Invoices;
invoiceCardDataGridView.DataSource = bs;
Community
  • 1
  • 1
Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198
  • No problem. Consider upvoting the answers that helped you and accepting the answer that helped you most (My vote goes to Zied) – Ohad Schneider Oct 31 '10 at 17:20