Function Expression on EntityView

Posts   
 
    
Posts: 7
Joined: 02-Jul-2015
# Posted on: 15-Jul-2015 17:17:36   

I'm trying to add a predicate expression to an EntityView that will filter out records where values of one of the fields have length < 5. There is no problem with the entity collection on which the view is based ("collectionPassedIn" below).

Here's the code I have so far:


Dim viewCollection as EntityView2(Of EntityClasses.AEntity)
Dim lengthFilter as PredicateExpression

viewCollection = New EntityView2(Of EntityClasses.AEntity)(collectionPassedIn)

lengthFilter = New PredicateExpression(AFields.Length => 5)

viewCollection.Filter = lengthFilter

Having a problem referring to the length of values (_AFields.Length_) within a field (or any other function off of a field) within a filter. Is it even possible?

Thanks for your help!

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 15-Jul-2015 17:43:09   

What's the type of the entityField?

Posts: 7
Joined: 02-Jul-2015
# Posted on: 15-Jul-2015 18:53:03   

It is a String.

Posts: 7
Joined: 02-Jul-2015
# Posted on: 15-Jul-2015 19:33:45   

I had previously used a DbFunctionCall for "LENGTH" when creating expressions for pulling the data into an entity collection. I didn't think it would work in this context - filtering an entity collection to create an entity view.

(The whole idea in this scenario is to pull all the data and filter out the few records with lengths that are too small in the code rather than in the database.)

But I went ahead and tried it. Didn't work.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 16-Jul-2015 10:25:09   

What you're doing is filtering on a field in the entities. So if you have a set of orders and you want to filter the view on only orders from customer "ALFKI" then you use a predicate like you do:

viewCollection.Filter = (OrderFields.CustomerId="ALFKI")

however you want to filter on a property of a value in an entity, so you have to do something else.

You have to use a DelegatePredicate<T>. Example:

[Test]
public void EntityViewFilteredOnDelegate()
{
    using(var adapter = new DataAccessAdapter())
    {
        var customers = new NWHC.EntityCollection<CustomerEntity>();
        adapter.FetchEntityCollection(customers, null);
        Assert.AreEqual(91, customers.Count);

        var view = new EntityView2<CustomerEntity>(customers);
        Assert.AreEqual(91, view.Count);

        view.Filter = new DelegatePredicate<CustomerEntity>(e => e.CompanyName.Length > 15);
        Assert.AreEqual(64, view.Count);
        foreach(var c in view)
        {
            Assert.IsTrue(c.CompanyName.Length > 15);
        }
    }
}

So it takes a lambda. In VB, this then becomes for you:

viewCollection.Filter = New DelegatePredicate(Of AEntity)(Function(e) e.FieldName.Length > 5)

Where FieldName is the field you want to filter on.

I had previously used a DbFunctionCall for "LENGTH" when creating expressions for pulling the data into an entity collection. I didn't think it would work in this context - filtering an entity collection to create an entity view.

If this didn't work, perhaps you specified the function call wrong? You can see the query being generated by enabling tracing, see 'Troubleshooting and Debugging' in the runtime manual.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 7
Joined: 02-Jul-2015
# Posted on: 22-Jul-2015 22:26:40   

That solved it. Thanks for your help.

smile