views:

26

answers:

1

The amount of items in collection: ~100k The amount of field displayed in columns: 4-10

The problem itself - the collection is taken from a database using EntityFramework. It takes about 10-12s on dev computers to load and materialize all the required data. Yet another thing that comes up is that the same collection can be bound to several controls, and, therefore, they must be filtered separately (= not setting the default collection view filters). Currently, I set the binding as follows:

Binding b = new Binding();
b.Source = new CollectionViewSource() { Source = MyLargeCollection }.View;
MyDataGrid.SetBinding(DataGrid.ItemsSourceProperty, b);

Creating a new CollectionViewSource greatly increases the time it takes to initialize - several minutes (and I suspect that it is enumerating the 100k collection for some reason). I mean that if I just set:

b.Source = MyLargeCollection;

It will just take those 10-12 seconds to load and materialize data from the database.

The question - is there some problem with my code? If not - what would be the right approach for binding the same large collection to different items controls but with different collection views?

+1  A: 

Just use Linq to Entities to load the entities with its specified filter to make sure you don't load all 10k records because no user is interested in a grid with 10k records.

Example of binding to a query:

grid1.DataContext = (from i in context.MyItems
                    where i.MyPropertyToFilter == "myFilter"
                    select i).ToList();

grid2.DataContext = (from i in context.MyItems
                    where i.MyOtherPropertyToFilter == "myOhterFilter"
                    select i).ToList();

In this way you only load the records needed for your controls

Wouter Janssens - Xelos bvba
Well, this only solves the problem partially. I understand that this is a neat way to filter and sort the resultset.Consider a case when you need to have something like 100k entries in one control (== or create a 'feeling' for the user that there are 100k entries there). What is the best way to optimize it? First thought - just query the needed data => data virtualization. Yet this will raise problems with such methods as IndexOf in the underlying collection and such.
Jefim
If you need such a functionality you will need to implement an own class that wraps your full collection that is not yet initialized and create custom implementations of Count, IndexOf, Indexer, ... A good suggestion is to implement IList<T>. Hope this helps you
Wouter Janssens - Xelos bvba
Well, I ended up querying partial data that does not get materialized and tracked by entity framework. At the same time I use SelectedValuePath=Id to select entities by id. This way the memory consumption is minimal. The time to load such a collection varies on my machine from 0.2 to 0.5 second for a set of 100k entities. The memory consumption is at approx 20-30 mb for two nvarchar(255) columns. This is just my case, not a benchmark.
Jefim
Implementing IList was an option, yet when you do a partial select (with some WHERE params) you still have a problem with IndexOf as it requires at least one more query to the database and EF does not actually support selecting the row number in the resultset. Thanks for the answer though. It got me going. :)
Jefim