Typed list index

Posts   
 
    
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Nov-2004 11:50:39   

Hi

I have a suggestion for the next update of LLGen. Right now as it stands, when you create a new typed list, the result set index is based on the ORDER (i.e click on) in which you add your fields to the typed list.

. As far as I can tell, the only way to know which order you result set will be in is to dig into the 'BuildResultset()' result method in the typed list class and check the 'IndexInResult' parameter in the '_fields.DefineField' lines. This parameter is hard coded from the order the field were clicked on when creating the typed list.

Mmmmm, seems to me that the 'IndexinResult' should come from a public property instead of being auto generated.

Why? Well, in the designer, first of all, there is no way to tell which field corresponds to the result set index, let alone allowing you to set the index you want. Second, if you need to get a typed list field index directly ex: your are trying to bind two fields to a name value pair, one should be able to do this using a property form your app's code such as:

    MycomboListBox.DataValueField = myTypedList.FieldIndex.Columns([myTypedList.FieldIndex])
    MycomboListBox.DataTextField = myTypedList.FieldIndex.Columns([myTypedList.FieldIndex])     

MycomboListBox.DataBind()

Just my two cents worth...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Nov-2004 12:39:20   

You can move fields in a typed list up/down in the project explorer: click open the typed list node and the fields node and select a field and with the rightmousebutton bring up the context menu and select move up /down. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Nov-2004 13:30:27   

Cool - I didn't realize that "Move up" "Move down" reordered the index when the code was re-generated. Maybe rewording that in next version to be a bit more clear?...

However, in my original message, are there any plans to expose the typed list filed index as a property from the typed list class itself?

Or maybe there is already a way to do that that I'm not aware of?

Stoop

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 16-Nov-2004 13:52:49   

Stoop wrote:

Cool - I didn't realize that "Move up" "Move down" reordered the index when the code was re-generated. Maybe rewording that in next version to be a bit more clear?...

To be certain: what's exactly not clear, as the field is selected and you can move it up or down, do you have any suggestions for these menu entries?

However, in my original message, are there any plans to expose the typed list filed index as a property from the typed list class itself? Or maybe there is already a way to do that that I'm not aware of? Stoop

THe fieldindexes are not generated because the typed list is based on existing fields.

However your code:


MycomboListBox.DataValueField = myTypedList.FieldIndex.Columns([myTypedList.FieldIndex])
MycomboListBox.DataTextField = myTypedList.FieldIndex.Columns([myTypedList.FieldIndex]) 
MycomboListBox.DataBind()

you can also write that:


MycomboListBox.DataValueField = "ValueFieldName";
MycomboListBox.DataTextField = "TextFieldName";
MycomboListBox.DataBind()

As it works just as with entitycollections.

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 16-Nov-2004 19:59:05   

Well, I dunno... Maybe adding a column in the 'Fields mapped on entity fields' tab might be better. At least you could easily see in what order your fields are in.

As for my other question: "are there any plans to expose the typed list filed index as a property from the typed list class itself?" Maybe I wasn't clear.

Yes, "THe fieldindexes are not generated because the typed list is based on existing fields", but that's not what I meant.

What I need is an enumeration (or property) that is exposed from the typed list class itself that returns an integer of the field's column index! You can easily get the fields index from the table it belongs to by using the 'MyTableFieldIndex.MyFieldName' enumeration, but obviously you can't use this because the field index in the table may not be the same in a typed list. What I would like to see is something along the lines of:

MyTypedListFieldIndex.MyFieldName

or maybe

MyTypedListColumnIndex.MyFieldName

that returns a 0 based integer starting with the first column

I can see lots of advantages to this. A (VERY) simple example:

myTextBox.Text = MyTypedList.Rows(0).Item(MyTypedListFieldIndex.MyFieldName).ToString()

or

myTextBox.Text = MyTypedList.Rows(0).Item(MyTypedListColumnIndex.MyFieldName).ToString()

If you ever rename this field or reorder the fields in the typed list, then regenerate the LLGen code, the above code won't break. I can think of other advantages, as well as you probably can, but the whole point is by being able to access the field's column index through a enumeration or property leads to more effecient non breakable code

Stoop

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 17-Nov-2004 10:26:08   

Stoop wrote:

What I need is an enumeration (or property) that is exposed from the typed list class itself that returns an integer of the field's column index! You can easily get the fields index from the table it belongs to by using the 'MyTableFieldIndex.MyFieldName' enumeration, but obviously you can't use this because the field index in the table may not be the same in a typed list. What I would like to see is something along the lines of:

MyTypedListFieldIndex.MyFieldName

or maybe

MyTypedListColumnIndex.MyFieldName

that returns a 0 based integer starting with the first column

I can see lots of advantages to this. A (VERY) simple example:

myTextBox.Text = MyTypedList.Rows(0).Item(MyTypedListFieldIndex.MyFieldName).ToString()

or

myTextBox.Text = MyTypedList.Rows(0).Item(MyTypedListColumnIndex.MyFieldName).ToString()

If you ever rename this field or reorder the fields in the typed list, then regenerate the LLGen code, the above code won't break. I can think of other advantages, as well as you probably can, but the whole point is by being able to access the field's column index through a enumeration or property leads to more effecient non breakable code

But... why would you use the typedlist in a datatable-kind of way? I mean, the typed list is different from a datatable, because it is typed: myTextBox.Text = MyTypedList(0).MyFieldName

Even if you re-order the fields, that won't break. However if you rename the field, it will, but an enum value will then also break, because it isn't there anymore. So protection against renaming breakage can only be solved if you use with hardcoded indexes, not based on a name simple_smile . (or I miss something)

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 17-Nov-2004 17:09:35   

Well, maybe that was not the greatest example in the world..

But still, there are times when programmers like myself need to access the column index, not the actual value. In my case, I use a generic name/value class that allows me to create name/value array lists simply by passing the typed list and the column indexes of the columns that I want to use as the name/value pair. As it stands right now, I have to pass the actual index as an integer to my name/value class. If I ever change my typed list, I always have to go back and adjust, if need be, the integer that represents the column indexes I need.

Instead of hard coding this integer value, it sure would be nicer if I simply could pass this value to my class in the form of 'MyTypedListFieldIndex.MyFieldName' or 'MyTypedListColumnIndex.MyFieldName'. That way if I ever change the typed list then I don't need to worry about having to go into my apps business logic to change the hard coded integer value. Again, I'm only speaking about my needs, but I'm sure that others probably use typed lists in similar manners.

All I'm saying is that maybe it the next upgrade, an enumeration for the field's column indexes is generated in the typed list class in question. If the typed list ever changes, then this enumeration changes accordingly when the code from LLGen is regenerated.

IMHP this would be a fantastic addition to LLGen

Stoop

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 17-Nov-2004 17:15:23   

Stoop wrote:

But still, there are times when programmers like myself need to access the column index, not the actual value. In my case, I use a generic name/value class that allows me to create name/value array lists simply by passing the typed list and the column indexes of the columns that I want to use as the name/value pair. As it stands right now, I have to pass the actual index as an integer to my name/value class. If I ever change my typed list, I always have to go back and adjust, if need be, the integer that represents the column indexes I need.

But, there is NO WAY you can keep this consistent if you rename a field in the typed list, then your code will break no matter what kind of enum field index you're using, as the name in the enum is different than from the one you're using in your own code.

Instead of hard coding this integer value, it sure would be nicer if I simply could pass this value to my class in the form of 'MyTypedListFieldIndex.MyFieldName' or 'MyTypedListColumnIndex.MyFieldName'. That way if I ever change the typed list then I don't need to worry about having to go into my apps business logic to change the hard coded integer value.

You can also accomplish that with using the column name as I suggested earlier. Of course, if you rename the field, this will break, but the code will also break when you use myTypedListFieldIndex.FieldName, as the name is no longer there.

Edit: so even though if I add the enum, which I'm very willing to do, it will not bring you much I'm afraid: field renames will break your code. Or am I overlooking something?

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 17-Nov-2004 21:21:36   

Thnx Otis for your reply

I'm just saying that there should be a enum thats generated in the typed list class that returns the integer value of the fields column index, thats all: 'MyTypedListColumnIndex.MyFieldName' for example.

Yes, renaming the field in a typed list of course would break the code. Same as breaking any code if you rename your field in the entity and are refering to in apps code it by the 'MyEntityFieldIndex.FieldName'enum. That is a gimme...

I'm not sure about other programmers, but I never (well.... almost never) rename field once I've added an entity for the first time. However, I often have to add fields from entities and reorder to typed lists. I try and keep that to a minimum, but I have clients that always want changes after I've done stuff.. Sad, but pretty normal especially when working with web apps.

That's why I think that my above mentioned suggestion would be a great addition to LLGen..

Stoop

PS I can't speak for other folks, but YES! an enum in the generated typed list classes returning the fields column index would be a LOT of help

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 18-Nov-2004 10:30:08   

Ok, if you want these enums follow these steps: (which are easier with the template studio beta)

1) create a copy of the templateset config you're using, for example VBNetTemplateSet.config, in the same folder 2) open the copy in a texteditor and change the name tag contents. 3) add a template binding: <templateBinding templateID="Custom_ConstantsEnumsTemplate" templateFilename="VB.NET\typedListEnumsInclude.template" /> 4) create a new file, typedListEnumsInclude.template, in the VB.NET directory of the templates folder of the driver you're using, for example drivers\Sqlserver\Templates\VB.NET, and open it in a texteditor 5) Add the following code to that template


<[Foreach TypedList CrLf]>
    ' /// <summary>
    ' /// Index enum to fast-access fields in the typedlist: <[CurrentTypedListName]>.
    ' /// Auto-generated, do not modify.
    ' /// </summary>
    Public Enum <[CurrentTypedListName]>FieldIndex
<[Foreach TypedListField  CrLF]>        [<[TypedListFieldName]>]<[NextForeach]>
        AmountOfFields
    End Enum
<[NextForeach]>

6) load your project into llblgen pro, press F7, and select the copy of the template set you made as the template set of choice. Generate code, et viola! simple_smile

To do this in template studio (available in beta from the Extra's section) 1) start template studio and click File -> New -> New Template Set From Existing... 2) Select the VBNetTemplateSet.config as the start template set, then after that give a new name, for example VBNetTemplateSetWithTypedListEnums.config 3) click Edit config 4) in the editor, add the template binding I pasted above in step 3) and save the config 5) click refresh viewer and double click the red 'typedListEnumsInclude.template' node, click Ok to create that file 6) copy/paste teh code I mentioned in the manual steps step 5 into the editor and save.

to test the template you open a project and click Generate -> Run Single Task. At the bottom select 'GenerateConstantsEnumsFile', at the participating objects tab, just select Typed Lists (first click the project node to de-select everything) and click Run task

the output is now visible in c:\temp\output\constantsEnums.vb (or another path if you've configurated the output path to a different folder simple_smile )

Frans Bouma | Lead developer LLBLGen Pro
Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 19-Nov-2004 08:59:15   

Thx Otis - I will give it a go

One question - will this be built into next update, though?

The reason I ask is because if I build a template using:

Public Enum <[CurrentTypedListName]>FieldIndex...

and in the next update you call it something else, just as an example:

Public Enum <[CurrentTypedListName]>ColumnIndex..

then that's not good. If it's going to be included in the next update, I would like to get the syntax straight now ahead of time.

Thx again Stoop

Stoop
User
Posts: 66
Joined: 28-Feb-2004
# Posted on: 19-Nov-2004 17:51:33   

Hi

Well, I did it and it works like a charm. However, I did make one little change that I feel is worth mentioning in case anyone is going to do the same or maybe if this will be included in future versions. In the 'typedListEnumsInclude.template' I changed what you suggested to:

' /// <summary> ' /// Typed list field (column) indexes ' /// </summary>

Region " Typed list field index enums "

<[Foreach TypedList CrLf]> ' /// <summary> ' /// Index enum to acess fields (column) index in typed list: <[CurrentTypedListName]>. ' /// Auto-generated, do not modify. ' /// </summary> Public Enum <[CurrentTypedListName]>TypedListFieldIndex <[Foreach TypedListField CrLF]> [<[TypedListFieldName]>]<[NextForeach]> AmountOfFields End Enum <[NextForeach]>

End Region

The important change is in the line:

Public Enum <[CurrentTypedListName]>TypedListFieldIndex

which I changed from just FieldIndex to TypedListFieldIndex

The reason was there was a conflict the first time I generated the code with an enum for an entity with the same name. As a rule, I name all my entities singular and all my typed lists plural. However, I had one enitity that is called 'CustomerTravelInfo' that really doesn't have a plural name, at least in English so I made a typed list with the same name. Of course, this gave me no problems before. Making the change in the above mentioned line gurantees no conflicts if anyone has typed lists with same name as an entity...

Thx again for your time & help

Stoop

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 20-Nov-2004 10:56:48   

Thanks for the fix, Stoop! simple_smile

I'll make sure it is rolled into the next upgrade for the templates. simple_smile

Frans Bouma | Lead developer LLBLGen Pro