views:

10843

answers:

6

I am using LINQ to query a generic dictionary and then use the result as the datasource for my ListView (WebForms).

Simplified code:

Dictionary<Guid, Record> dict = GetAllRecords();
myListView.DataSource = dict.Values.Where(rec => rec.Name == "foo");
myListView.DataBind();

I thought that would work but in fact it throws a System.InvalidOperationException:

ListView with id 'myListView' must have a data source that either implements ICollection or can perform data source paging if AllowPaging is true.

In order to get it working I have had to resort to the following:

Dictionary<Guid, Record> dict = GetAllRecords();
List<Record> searchResults = new List<Record>();

var matches = dict.Values.Where(rec => rec.Name == "foo");
foreach (Record rec in matches)
    searchResults.Add(rec);

myListView.DataSource = searchResults;
myListView.DataBind();

Is there a small gotcha in the first example to make it work?

(Wasn't sure what to use as the question title for this one, feel free to edit to something more appropriate)

+17  A: 

Try this:

var matches = dict.Values.Where(rec => rec.Name == "foo").ToList();

Be aware that that will essentially be creating a new list from the original Values collection, and so any changes to your dictionary won't automatically be reflected in your bound control.

Matt Hamilton
+1  A: 
myListView.DataSource = (List<Record>) dict.Values.Where(rec => rec.Name == "foo");
lomaxx
+1  A: 

You might also try:

var matches = new List<Record>(dict.Values.Where(rec => rec.Name == "foo"));

Basically generic collections are very difficult to cast directly, so you really have little choice but to create a new object.

Jon Limjap
A: 

@lomaxx : Your first solution does not work. I can't seem to be able to cast the result from the where clause to a List. It results in the following runtime exception:

*Unable to cast object of type 'd__01[Record]' to type 'System.Collections.Generic.List1[Record]'.*

Your second solution works great and so does Matt Hamiltons's. I've accepted Matt Hamiltons's answer as I found it 'cleaner'.

thank you both.

Christian Hagelid
+3  A: 

I tend to prefer using the new Linq syntax:

myListView.DataSource = (
    from rec in GetAllRecords().Values
    where rec.Name == "foo"
    select rec ).ToList();
myListView.DataBind();

Why are you getting a dictionary when you don't use the key? You're paying for that overhead.

Keith
A: 

@Keith: I'm using a the Guid key in the dictionary somewhere else in my code so I can get a record by record id.

Agree to disagree on the syntax ;)

Christian Hagelid