How get the number of fields in PK (at template time)?

Posts   
 
    
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 10-Aug-2009 09:08:37   

Hi to All,

I would like to generate different code for an entity in case it has compound PK.

So I have to write an IF

[IF...??? ... case if PK is only one field [ELSE... ... case if PK is composed by multiple fields.

I know how to iterate on PK fields: <[Foreach PrimaryKeyEntityField....

What to write to the [IF ???...] condition?

thx for answers. Horo

Walaa avatar
Walaa
Support Team
Posts: 14987
Joined: 21-Aug-2005
# Posted on: 10-Aug-2009 10:11:25   

You can put a counter inside the foreach loop and check on the value of the counter outside the loop, and you can generate the code as:

if (pkCounter == 1)
{
... case if PK is only one field
}
else if(pkCounter > 1)
{
... case if PK is composed by multiple fields.
}
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 11-Aug-2009 19:32:38   

Hi Walaa,

Thx for answer.

You mean I have to define a template variable? The code you wrote is a csharp code, not template code, or did you use as pseudo code to explain the conditional statement?

Sorry for the lame question, but It would be more helpful if the sample in your answer use the LLBLGen template language, because I do not know how to define a variable and write an [IF.... statement

thx

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 12-Aug-2009 05:03:47   

There are two template systems: LTP and TDL. If you want more grained control and have more flexibility you have to use LTP (this is the case). Walaa's pseudo-code is written in LTP. For more info, please read the SDK documentation.

David Elizondo | LLBLGen Support Team
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 12-Aug-2009 09:17:57   

Hi Daelmo,

Thx for your answer.

I would like to modify an original Adapter template with only a few line. So my original question about detecting composite PKs covers that case.

Is it possible with LTP?

thx

Walaa avatar
Walaa
Support Team
Posts: 14987
Joined: 21-Aug-2005
# Posted on: 12-Aug-2009 11:13:09   

You mean I have to define a template variable? The code you wrote is a csharp code, not template code

The following is a template code:

int counter = 0;
<[Foreach PrimaryKeyEntityField IncludeInherited CrLf]>
            counter++;
<[NextForeach]>

if (counter == 1)
{
   //your code here... case if PK is only one field
}
else if(counter > 1)
{
   //your code here... case if PK is composed by multiple fields.
}
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 12-Aug-2009 23:59:25   

Hi Walaa,

I would like to generate different code depending on PK is composite or not.

This is not the same as your solution which generates a runtime if conditional statement. I do not want generate runtime conditional statement.

thx

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 13-Aug-2009 04:38:36   

Again, I think you need to go on LTP instead of TDL, to gain flexibility on this. You can download some templates (ASP GUI generator, for instance) to see some examples.

David Elizondo | LLBLGen Support Team
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 13-Aug-2009 10:03:06   

Hi Daelmo,

Thx for your answer.

A bit confusing this 2 'sub' thread, I mean your and Walaa's answers. So I understand and appreciate yout answer, and in this 'sub' thread I asked a question to you, which is not answered yet:

I would like to modify an original Adapter template with only a few line. So my original question about detecting composite PKs covers that case.

Is it possible with LTP, which is your recommendation?

thx

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39769
Joined: 17-Aug-2003
# Posted on: 13-Aug-2009 10:54:04   

horo wrote:

Hi Daelmo,

Thx for your answer.

A bit confusing this 2 'sub' thread, I mean your and Walaa's answers. So I understand and appreciate yout answer, and in this 'sub' thread I asked a question to you, which is not answered yet:

I would like to modify an original Adapter template with only a few line. So my original question about detecting composite PKs covers that case.

Is it possible with LTP, which is your recommendation?

thx

The original templates use the TDL template language (please read the SDK docs at least briefly so you understand what is meant with TDL and Lpt wink ). TDL uses fixed statements and it is not a full language, so if a statement isn't defined in TDL for what you want to do (e.g. an if statement which checks whether a PK has 2 or more fields), it's not possible to use TDL for this task. You then need to use a .lpt template as an include template.

However, it's perhaps a good idea that you explain briefly what you want to change in the original templates, so maybe there's another way to accomplish what you want to do. Based on what you want to do, I can give you advice how to create an include template using the .lpt template system (which is simply similar to ASP.NET/codesmith etc., so you have to write more code but you can access the entire project object graph).

Frans Bouma | Lead developer LLBLGen Pro
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 13-Aug-2009 16:00:06   

Hi Otis,

Thx for clearing the problem.

It seems, that to my original question the answer is: not possible in TDL, so if I would like to add some feature to the original adapter template, which have to distinguish between the two cases (composit PK or not) .

Orginaly I did not want to use the support team's valuable time to solve my ideas.

What I orignaly would like to do is quite simple: Enhance the adapter template with a GetByPK, and GetPK() methods. GetByPK(...) is a static factory method, there was no problem implementing it. GetPK() should be an instance method, with no parameters, and its return value the type of the PK in case of simple PK, and a 'tuple' class composed from the composite PK types in case of composite PK.

That's why I have to distinguish the two case at 'generation time'

thx for answers: Horo

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39769
Joined: 17-Aug-2003
# Posted on: 14-Aug-2009 11:17:24   

The GetPK() method could be solved generically in the CommonEntityBase with a method which returns the values always in a tuple (with 1 or more cells). This way you don't have to generate a lot of code which is actually redundant (and use an .lpt include template).

Inside GetPK, you traverse the fields in the entity.Fields.PrimaryKeyFields. There's one caveat: inheritance hierarchies of TargetPerEntity, which have all fields of all types in their hierarchy in their Fields collection, so also the PK fields of supertypes. There's a helper routine in FieldsUtils which will give you the # of real PK fields.

As all pk fields of all supertypes in that situation have the same value, and you just want values, just grab the pk fields from the primarykeyfields collection for the count returned and obtain their real value using GetCurrentFieldValue.

So it comes down to something like:

public Tuple GetPk()
{
    int numberOfPkFields = FieldUtils.DetermineNumberOfPkFields(this.Fields.PrimaryKeyFields);
    List<object> pkValues = new List<object>();
    
    for(int i=0;i<numberOfPkFields;i++)
    {
        pkValues.Add(this.GetCurrentFieldValue(this.Fields.PrimaryKeyFields[i].FieldIndex));
    }
    
    return new Tuple(pkValues);
}
Frans Bouma | Lead developer LLBLGen Pro
horo
User
Posts: 41
Joined: 01-Sep-2005
# Posted on: 17-Aug-2009 21:54:05   

Hi Otis,

Thx for your answer.

Currently we are using .NET 3.5 and not 4.0 :-). I used 'tuple' term with its general meaning not as the upcoming Tuple type in 4.0.

Originaly I planed to generate a typed PK class for example AEntity could have a AEntityPK class, and instance method of AEntity GetPK returns an instance of class (or better: struct) AEntityPK.

Anyway, we will create a "less typed" workaround for it, based on your mentioned solution, for example a type independent run-time algorithm returns a list or a dictionary with PK.

again, thx for your valuable time, and support.

Horo