How to filter an entity collection

Posts   
 
    
Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 10-Nov-2007 12:04:16   

Hi, (Using Ver 2, Adapter, VB, SQL Server) & looking for some simple advice.

When maintaining simple lookup tables, I fetch the entire collection into a grid, allow changes then save the entire collection. I want to use the same concept for simple master/detail scenarios where data volumes are low (and there are few columns) by initially fetching the entire collections of master and detail, and saving the collections when finished.

Say I fetch the entire collection of Divisions and the entire collection of Departments. I use the collection of Divisions as a lookup to present only related Departments, in a grid.

a) I know how to use predicates to filter Departments when fetching from the database, but how do I filter Departments from the DepartmentEntity collection itself (an example would be useful)?

b) Do other developers do it this way, or do you only fetch related Departments and save these Departments back when a different Division is selected?

I think the solution is simple but I can't find it.

TIA simple_smile

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 11-Nov-2007 23:08:16   

Hi Markiemac,

I'm not sure to understand 100% your scenario. But I think you could:

Fetch entire collection of entire Divisions and prefetch the Departaments, so you would have the two entire collections related!

Does this make sense to you? and BTW, Are you using WinForms or ASP.NET?

David Elizondo | LLBLGen Support Team
Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 13-Nov-2007 01:16:41   

Hi Daelmo,

Thanks for the reply. I'm using WinForms and I don't have a problem fetching what I need from the db to the EntityCollection, which is the datasource for my grid. But having got it there I want to filter the in-memory collection to present to the grid, only the Departments for a selected Division.

This filtered subset can then be updated, and a different set of departments then selected, again from the in-memory collection. When finished I would just persist the entire collection of Departments.

However, the only means of presenting a subset of an in-memory collection seems to be via the EntityView2 object, but the manual says:

The EntityView2 is a class which is used to create in-memory views on an EntityCollection object (generic or non-generic) and allows you to filter and sort an in-memory EntityCollection without actually touching the data inside the EntityCollection.

So if use of EntityView2 means that the data inside the collection is not touched, what else can I use to filter a subset of the in-memory collection to a grid for updating.

Hope I've explained my puzzellement and I'm sure it obvious, but not right now.

Thanks again

simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 13-Nov-2007 06:14:40   

Markiemac wrote:

Hi Daelmo,

Thanks for the reply. I'm using WinForms and I don't have a problem fetching what I need from the db to the EntityCollection, which is the datasource for my grid. But having got it there I want to filter the in-memory collection to present to the grid, only the Departments for a selected Division.

This filtered subset can then be updated, and a different set of departments then selected, again from the in-memory collection. When finished I would just persist the entire collection of Departments.

However, the only means of presenting a subset of an in-memory collection seems to be via the EntityView2 object, but the manual says:

The EntityView2 is a class which is used to create in-memory views on an EntityCollection object (generic or non-generic) and allows you to filter and sort an in-memory EntityCollection without actually touching the data inside the EntityCollection.

So if use of EntityView2 means that the data inside the collection is not touched, what else can I use to filter a subset of the in-memory collection to a grid for updating.

Hope I've explained my puzzellement and I'm sure it obvious, but not right now.

Thanks again

I think that quote has mislead you - what it means is that the EntityView provides a wrapper around the collection showing a filtered subset of the EntityCollection. Exactly the same as a DataView does for a DataTable.

Although you are binding your grid to an EntityCollection, because it supports IListSource your grid is actually redirected to a DataView object anyway and you can access this via the DefaultView property on the EntityCollection. So just set DefaultView.Filter to an IPredicate of your choice and the grid will show only the filtered entities.

Alternatively, you could create your own DataView which wraps your Collection and bind that to the grid instead. The difference between the two methods is that DefaultView will be used by all objects bound to the Collection and they will see the same filtering etc. By creating your own View, only objects bound to that View will see the filtering which may be what is required.

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39908
Joined: 17-Aug-2003
# Posted on: 13-Nov-2007 11:10:11   

simmotech wrote:

Although you are binding your grid to an EntityCollection, because it supports IListSource your grid is actually redirected to a DataView object anyway and you can access this via the DefaultView property on the EntityCollection. So just set DefaultView.Filter to an IPredicate of your choice and the grid will show only the filtered entities.

Alternatively, you could create your own DataView which wraps your Collection and bind that to the grid instead. The difference between the two methods is that DefaultView will be used by all objects bound to the Collection and they will see the same filtering etc. By creating your own View, only objects bound to that View will see the filtering which may be what is required.

s/DataView/EntityView(2)/gc

wink

Frans Bouma | Lead developer LLBLGen Pro
Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 13-Nov-2007 15:08:36   

Aahh the View is becoming clearer (sorry about the pun)smile

Frans, would you mind translating

s/DataView/EntityView(2)/gc

Thanks guys simple_smile

Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 14-Nov-2007 00:58:48   

...but not quite there yet. <EDIT>

having already fetched the BudgetDivisionEntity collection during form open, I'm now trying to filter it on FYear & Division using the code below:

    Function GetBudgetDivAllocationView(ByVal DivCode As String, ByVal FYear As Integer) As EntityView2(Of BudgetDivisionEntity)
        Dim budgetDivision As New EntityCollection(Of BudgetDivisionEntity)(New BudgetDivisionEntityFactory())
        Dim budgetDivisionView As New EntityView2(Of BudgetDivisionEntity)(budgetDivision)
        Dim adapter As New DataAccessAdapter
        Try
            Dim filter As New PredicateExpression(BudgetDivisionFields.FinancialYear = FYear)
            If Not String.IsNullOrEmpty(DivCode) Then
                filter.AddWithAnd(New PredicateExpression(BudgetDivisionFields.DivisionCode = DivCode))
            End If
            budgetDivisionView.Filter = filter
             Return budgetDivisionView
        Finally
            adapter.Dispose()
        End Try
    End Function

..but I'm getting nothing back. Can anyone see where I'm going wrong? (Using V2, Adapter, VB, SQL 2K, WinForms) disappointed

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 14-Nov-2007 11:32:17   

Function GetBudgetDivAllocationView(ByVal DivCode As String, ByVal FYear As Integer) As EntityView2(Of BudgetDivisionEntity) Dim budgetDivision As New EntityCollection(Of BudgetDivisionEntity)(New BudgetDivisionEntityFactory()) Dim budgetDivisionView As New EntityView2(Of BudgetDivisionEntity)(budgetDivision) Dim adapter As New DataAccessAdapter Try Dim filter As New PredicateExpression(BudgetDivisionFields.FinancialYear = FYear) If Not String.IsNullOrEmpty(DivCode) Then filter.AddWithAnd(New PredicateExpression(BudgetDivisionFields.DivisionCode = DivCode)) End If budgetDivisionView.Filter = filter Return budgetDivisionView Finally adapter.Dispose() End Try End Function

Should the collection already be fetched because you instantiate it within the method. Or you should fetch it within the method, I don't see any fetch method called. i.e. the adapter object was never used.

The EntityView works on Fetched Collections. It doesn't fetch the collection for you.

Markiemac
User
Posts: 132
Joined: 25-Apr-2006
# Posted on: 14-Nov-2007 21:48:34   

Walaa, Thanks for your insight.

I now pass the collection of previously fetched BudgetDivisions to the function below, for a filtered set to be returned:

Function GetBudgetDivAllocationView(ByVal allBudgetDivisions As EntityCollection(Of BudgetDivisionEntity), ByVal DivCode As String, ByVal FYear As Integer) As EntityView2(Of BudgetDivisionEntity)
    Dim budgetDivision As EntityCollection(Of BudgetDivisionEntity) = allBudgetDivisions
    Dim budgetDivisionView As New EntityView2(Of BudgetDivisionEntity)(budgetDivision)
    Dim adapter As New DataAccessAdapter
    Try
        Dim filter As New PredicateExpression(BudgetDivisionFields.FinancialYear = FYear)
        If Not String.IsNullOrEmpty(DivCode) Then
            filter.AddWithAnd(New PredicateExpression(BudgetDivisionFields.DivisionCode = DivCode))
        End If
        budgetDivisionView.Filter = filter
        Return budgetDivisionView
    Finally
        adapter.Dispose()
    End Try
End Function

I now get a filtered subset returned. Do you see any issues with the use of EntityView2 above or the function in general?

Thanks simple_smile

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Nov-2007 10:20:21   

Just the adapter is not needed.