tags:

views:

474

answers:

4

I'm working through the "Data Binding" chapter in Pro WPF in C# 2008.

They have you set up this class:

public class StoreDB
{
    public Contact GetContact(int id) {...}
    public List<Contact> GetContacts() {...}
}

The idea is to call these methods, getting either a Contact or a List<Contact> and bind these to the appropriate controls using LINQ on the latter method to filter/sort your objects.

This all makes sense.

However, what happens when you have 100,000 contacts and you want to get 3 of them? Your GetContacts() method gets 100,000 and your LINQ picks out three of them?

Isn't this super inefficient?

How are real-world applications built to avoid this?

+1  A: 

Hi, I dont know the book your using but the question here is what database are you using if its SQL then you can use LINQ to SQL and add a dbml file to your project through the VS designer, then just drag the tales you want to use from the Sever Explorer view onto the the dbml and all your bussness object classes will be auto generated.

From there you can use the dataContex created and work with linq to filter the results before they are fetched.

What you have been doing right now is filtering the objects you fetched through a diffrent means.

HTH, Eric

+1  A: 

Hi Edward, Since you have been asking may WPF and LINQ quetions i thought you would really want to take a look at some good vido traning for WPF and LINQ or ADO.net,

this is an excelt source to start learning very straight forward.

Vido Traning WPF

HTH, Eric

+2  A: 

I would recommend a design that does not have GetContacts returning List<T>. I'm not entirely sure that you would like to use List<T> because the collection you are returning is mutable. In WPF if you'd truly like a mutable list of items try ObservableCollection<T>.

However, I think the best interface would return an IEnumerable<T> which is the result of your SQL or LINQ query. This will provide an immutable collection of your contacts to the binder, which can be filtered with LINQ to Objects simply and easily.

sixlettervariables
Does IEnumerable<T> return the data all at once, or does it act like IQueryable<T> and only process the data when it is accessed?
Peter M
IEnumerable<T> data access is based on the implementation. It could be deferred or it could be immediate.
sixlettervariables
+1  A: 

Welcome in the Linq world!

You want to return an IQueryable<Contact>:

public class StoreDB
{
    public Contact GetContact(int id) {...}

    // change to this:
    public IQueryable<Contact> GetContacts() {...}
}

Now you can say this without wasting cycles or bandwidth:

IQueryable<Contact> SerachByFirstName(StoreDB store, string searchParam, int limit) 
{
    return store.GetContacts()
        .Where(c => c.FirstName == searchParam)
        .Take(limit);
}

In fact, this still won't dispatch a query to the database unless you start enumarting over the IQueryable. That is, you still can add more Where() or OrderBy() or what ever and they will be merged and sent to the source together when the query is finally evaluated.


Of course this doesn't help you to bind to the UI. But that is a hard problem. You either have to expose the underlying EntitySet to WPF or use a MVVM (or similar) architecture to separate data access and UI.

David Schmitt
yes, this is what I want to do, but the above causes "The type System.Collections.Generic.IEnumerable<dpwpf.Contact> cannot be converted to System.Linq.IQueryable<dpwpf.Contact>". What do I need to use beside List<Contact>, since IQueryable<Contact> doesn't work because it's abstract.
Edward Tanguay
enhanced my answer
David Schmitt