PredicateExpression confused by enums...

Posts   
 
    
JSobell
User
Posts: 145
Joined: 07-Jan-2006
# Posted on: 18-Apr-2008 02:43:24   

We've just found that if you specify a PredicateExpression such as:

CustomerFields.Permission == eMyPermissions.ViewOnly

then the SQL that is generated is something like

"WHERE Permission = 'ViewOnly' "

In our case the eMyPermissions enum is datatype long, but we've not done any further testing to see if applies to other enum types. Should all enum parameters not be handled internally as their numeric equivalent?

Casting the enum to a (long) obviously solves the problem, but it's counter-intuitive and not detected until a runtime exception occurs.

Cheers, Jason

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 18-Apr-2008 09:32:32   

Which exact version of the llblgen runtime library are you using?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 18-Apr-2008 10:16:18   

That has to be handled by your typeconverter. If your typeconverter converts the enum to a long, a long value is passed in the parameter (so it's not converted as a string, but as a numeric parameter).

Why do you use enums as longs btw? IMHO it's pretty hard to define more than 2billion values in an enum wink

Frans Bouma | Lead developer LLBLGen Pro
JSobell
User
Posts: 145
Joined: 07-Jan-2006
# Posted on: 19-Apr-2008 16:48:01   

Otis wrote:

That has to be handled by your typeconverter. If your typeconverter converts the enum to a long, a long value is passed in the parameter (so it's not converted as a string, but as a numeric parameter).

Why do you use enums as longs btw? IMHO it's pretty hard to define more than 2billion values in an enum wink

We use the values as a bitmap to allow 64 permissions... we don't actually have 2billion values simple_smile

OK, so do we have to always use a typeconverter when we reference an enum in a PredicateExpression? Does the Predicate builder get confused between Field enums and others? It just seems odd (and very un-LLBLGen-like) to have a situation where the type-safe functionality is lost and errors are only detected when invalid SQL is generated.

I can tell our web developer to make sure he casts every enum expression, but I'm wondering whether this is a solution or a 'workaround' simple_smile

Cheers, Jason

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 19-Apr-2008 21:17:05   

As far as I know enum types return its string representation by default:

eMyPermissions.ViewOnly // this will return "ViewOnly"

If you need the numeric representation you need to cast:

(long)eMyPermissions.ViewOnly // this will return 50 (for instance)

So, if you don't have compile errors is because your field is string (I guess).

TypeConverters are a good place to do these conversions. yourTypeConverter know that some numeric value (ex. 50) should represent some enum value(ex: eMyPermissions.ViewOnly). Then the field's type becomes eMyPermissions. Then the following line is valid:

CustomersFields.Permission = eMyPermissions.ViewOnly
// this line will generate the following SQL:
// WHERE Permission = '50'

Take a look at this post to write you own typeconverter: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7355

Cheers.

simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 20-Apr-2008 06:29:26   

Would it not be relatively easy to add operator overloads for enums?

If the datafield is expecting a string then use ToString() otherwise attempt to convert it numerically to the expected numeric type.

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 20-Apr-2008 11:08:21   

That's not necessary, because if a field is of an Enum type, the field automatically must have a typeconverter.

If you don't use a typeconverter to set the field's type to an enum type but leave it as a numeric type, e.g. int, then you have to cast the enum value to int.

Sure, we could build into the field compare value predicate a check whether the object to compare with is an enum type and the field isn't, but IMHO it encourages sloppy programming: if you use enums in your program for numeric constants, which is a good thing, and you want to use them in areas where they've to be used as their numeric value, you have to cast yourself.

Though it isn't a big change in the predicate class for us, although it hardly ever occurs this way, as most people who use enums together with fields set the field of the enum type through a typeconverter.

Frans Bouma | Lead developer LLBLGen Pro