Like

Posts   
 
    
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 29-May-2006 17:30:32   

I'm using a like predicate expression on a EntityView2

In the manual it says

Field LIKE "Foo%" FieldLikePredicate

This indicates a starts with Foo.

filter.AddWithAnd(PredicateFactory.Like(InvoiceFieldIndex.BillYyyyMm, dc.FilterText));

But when I use it it seems to be doing Field LIKE "%Foo%" (Contains Foo)!

Also is there a way to get a Field LIKE "%Foo" (Ends with Foo)?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 29-May-2006 18:17:46   

What's FilterText in that line of code, "Foo%" ? It can be the interpretation logic of the FieldLikePredicate is a little buggy, so I need to know exactly what the value of the pattern is you pass to the predicatefactory call simple_smile

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 29-May-2006 18:41:47   

Just as string without the percent. i.e. "2006-0".

Does it accept wildcards or a regex? (If it did take a regex it would be great.)

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 29-May-2006 19:15:38   

arschr wrote:

Just as string without the percent. i.e. "2006-0".

Does it accept wildcards or a regex? (If it did take a regex it would be great.)

It works exactly the same as a like statement. So if you pass in "Foo%" it should match with Foo, Foof but not with fop.

It actually uses the pattern as a regex simple_smile It replaces % with .* and for the rest uses the pattern as a regex.

But back to the situation at hand: So you pass in a string without a wildcard and it matches with the wrong values?

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 29-May-2006 19:40:37   

Yes,

If I pass it "20", it is leaving "205Q926668" and "706Q928200" in the filtered EntityView.

You are saying we need to embed the % in the compare value ourselfs?

It actually uses the pattern as a regex Regular Smiley It replaces % with .* and for the rest uses the pattern as a regex.

That explains it. it doesn't replace anything and the regex "20" matches both of those values. I'm not sure that is bad, in fact it very well may be good.

What does "20." mean? "^20.", "^.20.", or "^.20.$" or something else?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 29-May-2006 20:29:30   

arschr wrote:

Yes,

If I pass it "20", it is leaving "205Q926668" and "706Q928200" in the filtered EntityView.

You are saying we need to embed the % in the compare value ourselfs?

I think I know what's wrong. "20" is passed as the regex pattern, though 20 matches of course with 205Q... and 32432203432. I have to check how I can solve this.

It actually uses the pattern as a regex It replaces % with .* and for the rest uses the pattern as a regex.

That explains it. it doesn't replace anything and the regex "20" matches both of those values. I'm not sure that is bad, in fact it very well may be good.

What does "20." mean? "^20.", "^.20.", or "^.20.$" or something else?

20.* means 20 followed by 0 or more characters which aren't \r or \n.

I've to think about what exactly should be expected. I think if you want a fixed match, you should use a fieldcomparevalue predicate. Otherwise it's a pattern match, but it can give problems, because if you want Foo%, you of course don't want something like 'aFoop' matching your filter.

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 29-May-2006 21:39:34   

20.* means 20 followed by 0 or more characters which aren't \r or \n.

Yes, that is what I was implying.

I think you should allow us to pass in the actual regex, even if that means a client only predicate, since Sql doesn't support very rich wildcard syntax.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 29-May-2006 22:20:58   

Yeah, I think I'll solve it by checking if the 'match at beginning/end of line' is present when teh string is passed in. if not, it will be added. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 30-May-2006 12:33:02   

I've added a flag to signal it's a regex. This was the only way to really solve it, as it otherwise would be impossible to match a '%' in a string.


[Test]
public void LikeFilterInMemoryTest()
{
    NWHC.EntityCollection<CustomerEntity> customers = new NWHC.EntityCollection<CustomerEntity>( new CustomerEntityFactory() );
    using( DataAccessAdapter adapter = new DataAccessAdapter() )
    {
        adapter.FetchEntityCollection( customers, null );
    }

    EntityView2<CustomerEntity> customerView = customers.DefaultView;

    // filter on A%. Don't specify it's a regex.
    customerView.Filter = (CustomerFields.CompanyName % "A%");
    Assert.AreEqual( 4, customerView.Count );

    // filter on %e%. Dont specify it's a regex
    customerView.Filter = (CustomerFields.CompanyName % "%e%");
    Assert.AreEqual( 76, customerView.Count );

    // filter on %s. Dont specify it's a regex
    customerView.Filter = (CustomerFields.CompanyName % "%s");
    Assert.AreEqual( 23, customerView.Count );

    // all names which have 3 parts
    FieldLikePredicate filter = (FieldLikePredicate)(CustomerFields.CompanyName % @"^\w+ \w+ \w+$");
    filter.PatternIsRegEx = true;
    customerView.Filter = filter;
    Assert.AreEqual( 23, customerView.Count );
    foreach( CustomerEntity customer in customerView )
    {
        string[] parts = customer.CompanyName.Split(' ');
        Assert.AreEqual( 3, parts.Length );
    }
}

As you can see, the regex has to contain start and end match markers (^ and $), though that's because ofthe nature of the regular expressions.

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 894
Joined: 14-Dec-2003
# Posted on: 30-May-2006 12:44:05   

This look good.