Hierarchy and Create-method

Posts   
 
    
ChBaeumer
User
Posts: 175
Joined: 23-Oct-2003
# Posted on: 02-Feb-2010 11:00:54   

Hi,

in my project I have serveral root entites and I like to define a static create method to instantiate the appropiate sub-entities using the discriminator value.

So far I have following:


<[ If IsSuperType ]>        
public static <[ RootEntityName ]>DTO Create( Guid elementTypeId )
<[ Foreach Entity CrLf ]>
<[ If Not StringValueEquals DiscriminatorValue "" ]>            
    if ( elementTypeId.Equals( <[ DiscriminatorValue ]> ) ) 
    { 
        return new <[ CurrentEntityName ]>DTO(); 
    }<[ EndIf ]>
<[ NextForeach ]>
}<[ EndIf ]>

Following problems:

  1. How do I get the .Net type of the Discriminator-Column? This is necessary for the parameter declaration of the method.
  2. How do I get all Subtypes of an root entity?
  3. DiscriminatorValue seems not to be evaluated for StringValueEquals so it is not possible to check if an Value exists for the solution above

Any hints

Christoph

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 02-Feb-2010 12:01:55   

Is this for DTOs or Entities? btw, Would you please explain why do you need this?

ChBaeumer
User
Posts: 175
Joined: 23-Oct-2003
# Posted on: 02-Feb-2010 12:22:06   

This would be for DTO although I could think of using this for entities to.

I have some meta data like

<Entity>Type <-> <Entity>

as Example

ElementType <-> Element

The ElementType is the meta data for element and describes the behaviour of the element. Both entities are linked with foreign key and the FK is used as discriminator.

Within the code the disciminator field is used to create the specific instance of the element. So instead of writing "new Role()" ( btw Role is a subtype of Element ) i would like to write:


Element.Create( DiscriminatorValue )

This is for convinience as the GUI allows to create all type of element. In order to get rid of following


    if ( RoleId.Equals( ElementTypeId )) { return new Role() }
    if ( EmployeeId.Equals( ElementTypeId )) { return new Employee() }
    if ( ProjectId.Equals( ElementTypeId )) { return new Project() }
    ...

RoleId, EmployeeId, ProjectId are constants and are linked to the ElementType.

Christoph

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39588
Joined: 17-Aug-2003
# Posted on: 03-Feb-2010 11:06:16   

ChBaeumer wrote:

Hi,

in my project I have serveral root entites and I like to define a static create method to instantiate the appropiate sub-entities using the discriminator value.

So far I have following:


<[ If IsSuperType ]>        
public static <[ RootEntityName ]>DTO Create( Guid elementTypeId )
<[ Foreach Entity CrLf ]>
<[ If Not StringValueEquals DiscriminatorValue "" ]>            
    if ( elementTypeId.Equals( <[ DiscriminatorValue ]> ) ) 
    { 
        return new <[ CurrentEntityName ]>DTO(); 
    }<[ EndIf ]>
<[ NextForeach ]>
}<[ EndIf ]>

Following problems:

  1. How do I get the .Net type of the Discriminator-Column? This is necessary for the parameter declaration of the method.
  2. How do I get all Subtypes of an root entity?
  3. DiscriminatorValue seems not to be evaluated for StringValueEquals so it is not possible to check if an Value exists for the solution above

v2.6 TDL doesn't have the proper statements to do this, e.g. it doesn't have a foreach for all subtypes. You can easily create this in .lpt btw. You can include a .lpt template inside a TDL template so you can use the lpt template as an include in the TDL based entity templates without problem.

When using a .lpt include template, you've to work with the _activeObject member variable, which is a Hashtable, (see 'Grammar' section in SDK docs in lpt templates engine section), and the key "CurrentEntity" contains the current entity definition.

Your code then becomes:


<%
    EntityDefinition entity = (EntityDefinition)((Hashtable)_activeObject)["CurrentEntity"];
    if((entity!=null) && entity.IsHierarchyRoot && (entity.HierarchyType==InheritanceHierarchyType.TargetPerEntityHierarchy))
    {
%>public static <%=entity.Name%>DTO Create(<%=entity.DiscriminatorField.DotNetType.ToString()%> elementTypeId)
{
<%
    foreach(EntityDefinition subType in entity.GetSubTypes(false))
    {
%>  if( elementTypeId.Equals( <%=subType.DiscriminatorValue%> )) 
    { 
        return new <%=subType.Name%>DTO(); 
    }
<%  }
%>} 

Haven't tested it but I think it should work properly. Pay special attention to subType.DiscriminatorValue, which is dumped into the output as-is. If your typeid is a Guid, you might want to compare the values in string form, or at least you need some support code to get working output.

For v3, this code has to be adjusted, however it won't be hard to migrate it (e.g. you ask the project for subtypes instead of the entity, you would also use the helper classes we're currently adding for .lpt templates for discriminator value output rather than this code above. )

Frans Bouma | Lead developer LLBLGen Pro