ToValue<T>() syntax

Posts   
 
    
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 14-Mar-2019 10:29:04   

Just curious as to why the above syntax works as it does.

I understand it is a placeholder for a lamba func; I understand it needs to have a value return type; I think I understand that the return type _may _need to be changed from field's defined result type;

But I can't help wondering why the EntityField can't have a <defaultResultType> ToValue() method (or Value property or whatever) autogenerated so the syntax in queries is cleaner in 99% of cases - and saves me having to lookup whether a field returns int or short etc.

I am sure you have looked into this before but I'd love to know why it isn't possible.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 14-Mar-2019 11:53:52   

Yeah it's quite cumbersome simple_smile Sadly there's no easy solution. The problem is that the expressiontree works with types, so it contains a call to ToValue<T>(). This is then picked up by the visitor which can determine the T type and build the right projector (and replace the ToValue<T>() with a read from a structure/array/datareader etc.)

If it would be a .ToValue() then it would be an untyped method and the type it would return would be unknown as the EntityField/expression object it's called on is untyped as well: CustomerFields.CompanyName returns an EntityField2 typed object that's untyped, i.e. it's not EntityField2<string>. We otherwise could add a public T ToValue() {} method which would return T and we would be able to determine it from there. Changing the entity field objects to generic typed objects is something that's on the list of things to refactor in the future but it's not without problems (and potentially breaking changes) hence we didn't proceed with it (yet).

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 14-Mar-2019 12:47:02   

Right - I now get the bit about EntityField2 being an untyped object.

Instead of returning EntityField2<string>, with all the problems of generics that includes, could it not return StringEntityField2 where that inherits from EntityField2? (similarly having Int32EntityField2, ByteEntityField2 etc.)

This is still is an EntityField2 so would eliminate or at least reduce significantly changes to existing code but in this expression tree scenario includes enough information for the right projector to be used?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 14-Mar-2019 13:55:44   

yes, in theory that could be the case. for types that aren't directly supported (but are supported through a type converter, like a custom enum) that's going to be a bit of a struggle but could be generated in the code.

There are some dynamic scenarios where this doesnt' work tho, e.g. in expressions: what type does the expression have? The .ToValue<T>() describes the type, but in this new scenario what type does the end result have? That depends on the operator/function used for instance.

For queryspec there's another route: to get the projection (with ToValue<T>() calls) generated by the ProjectionLambdaCreator https://www.llblgen.com/Documentation/5.5/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/QuerySpec/gencode_queryspec_projections.htm#projectionlambdacreator which uses the fields object and the target poco and creates the expression. Projecting to an anonymous type however does require the specification of the types...

Frans Bouma | Lead developer LLBLGen Pro