Hi Abel,

When we subclass a persistent class and we need that this subclass have a own storage we need to add in the inheritance class list the %Persistent class  first of all classes.

Shared storage

 Class sample.MyHL7 Extends EnsLib.HL7.Message
{ 

Storage Default
{
<Type>%Library.CacheStorage</Type>
}

}

Own storage

 Class sample.MyHL7 Extends (%Persistent, EnsLib.HL7.Message)
{ 

Storage Default
{
<Data name="MyHL7DefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>ParentId</Value>
</Value>
<Value name="3">
<Value>DocType</Value>
</Value>
<Value name="4">
<Value>Envelope</Value>
</Value>
<Value name="5">
<Value>Source</Value>
</Value>
<Value name="6">
<Value>IsMutable</Value>
</Value>
<Value name="7">
<Value>OriginalDocId</Value>
</Value>
<Value name="8">
<Value>MessageTypeCategory</Value>
</Value>
<Value name="9">
<Value>TimeCreated</Value>
</Value>
</Data>
<Data name="UserValues">
<Attribute>UserValues</Attribute>
<Structure>subnode</Structure>
<Subscript>"UserValues"</Subscript>
</Data>
<DataLocation>^sample.MyHL7D</DataLocation>
<DefaultData>MyHL7DefaultData</DefaultData>
<IdLocation>^sample.MyHL7D</IdLocation>
<IndexLocation>^sample.MyHL7I</IndexLocation>
<StreamLocation>^sample.MyHL7S</StreamLocation>
<Type>%Library.CacheStorage</Type>
} 

}

Hi Davi,

A simplest way is creating a datatype class:

 Class system.dto.sector.SectorStatusEnum Extends %Integer [ ClassType = datatype ]
{
 
Parameter DISPLAYLIST = ",Active,Inactive,Production,Upkeep,NewValue";

Parameter VALUELIST = ",1,2,3,4,5"; 

}

And use the datatype in your class:

Class system.dto.sector.Test Extends %Persistent
{ 

Property SectorStatus As SectorStatusEnum;

}

Example:

Hi Javier, 

A some years ago I wrote a class to copy from to object. Is a simple data tranformation that reads the definition of source object and try to set the target object.

Is a very simple copy, without care about with types, I use for save time when I need to copy many properties of source object  to target object.

Recently I adapted the code to consider the source objects that are dynamic objects.

Works similar to the method from JSON that Chris wrote in the post.

The code was written in portuguese (Brazil) I hope can be useful to you.

/// <p>
/// <b>2012-03-01 - Cristiano José da Silva</b><br/>
/// Classe utilizada para copiar todas propriedades de um objeto origem para um objeto destino.<br/>
/// Esse método não se comporta como o %ConstructClone, pois ele copia os dados de origem para um 
/// destino mesmo sendo de tipos diferentes. Ele foi implementado para poder copiar objetos de tipos 
/// diferentes mas com a mesma definição.<br/>
/// A definição mandatória é a da origem, isto é, caso o objeto destino possua um referência para outro
/// objeto, e no objeto origem essa mesma propriedade seja uma string, o objeto destino receberá uma string 
/// no lugar de uma referência.<br/>
/// Caso queira ignorar uma ou mais propriedade passa-las em no array pProriedadesAIgnorar indexao pelo nome 
/// da propriedade Ex:
/// <example>
/// Set tPropriedadesIgnoradas("Prop1") = 1
/// Set tPropriedadesIgnoradas("PropN") = 1
/// </example>
/// <strong>
/// Os nomes das propriedades devem ser exatamente iguais nas duas classes.</br>
/// Os tipos também devem ser os mesmos para evitar erros.
/// </strong><br/>
/// </p>
Class cjs.dt.CopiarObjetoDT Extends Ens.DataTransform [ ProcedureBlock ]
{

ClassMethod Transform(pSource As %RegisteredObject, pTarget As %RegisteredObject, ByRef pProriedadesIgnoradas) As %Status
{
    #Dim tException As %Exception.General
    #Dim tStatus As %Status = $System.Status.OK() 
    Try
    {
        If ($IsObject($Get(pSource)) '= 1) 
        {
            Set tStatus = $System.Status.Error(5001, "Objeto origem é obrigatório")
            //
            Quit
        }
        If ($IsObject($Get(pTarget)) '= 1) 
        {
            Set tStatus = $System.Status.Error(5001, "Objeto destino é obrigatório")
            //
            Quit
        }
        // Trata Objetos Dinâmicos (JSON)
        If (pSource.%IsA("%Object"))
        {
            #Dim tIterator As %Iterator.AbstractIterator = pSource.$getIterator()
            #Dim tChave As %String = ""
            #Dim tValor As %String = ""
            //
            While (tIterator.$getNext(.tChave, .tValor))
            {
                If ($Data(pProriedadesIgnoradas))
                {
                    Continue:($Get(pProriedadesIgnoradas(tChave), 0))
                }
                Set $Property(pTarget, tChave) = tValor
            }
        }
        Else
        {
            Set tDefinicaoClasse                   = ##Class(%Dictionary.CompiledClass).%OpenId(pSource.%ClassName(1))
            #Dim tPropriedades As %ArrayOfObjects  = tDefinicaoClasse.Properties
            #Dim tIndicePropriedade As %Integer    = 0
            //
            For tIndicePropriedade = 1 : 1 : tPropriedades.Count()
            { 
                #Dim tPropriedade As %Dictionary.CompiledProperty = tPropriedades.GetAt(tIndicePropriedade)
                //
                Continue:(tPropriedade.Private || tPropriedade.ReadOnly || tPropriedade.Calculated || tPropriedade.Transient)
                //
                #Dim tNomePropriedade As %String = tPropriedade.Name
                //
                If ($Data(pProriedadesIgnoradas))
                {
                    Continue:($Get(pProriedadesIgnoradas(tNomePropriedade), 0))
                }
                Set $Property(pTarget, tNomePropriedade) = $Property(pSource, tNomePropriedade)
            }
        }
    }
    Catch (tException)
    {
        Set tStatus = tException.AsStatus()
    }
    Return tStatus
}

ClassMethod Teste()
{
    Write !, "Teste ambos sendo um objeto registrado", !
    //
    Set tOrigem             = ##Class(Ens.StringContainer).%New()
    Set tOrigem.StringValue = "Ambos registrado."
    Set tDestino            = ##Class(Ens.StringContainer).%New()
    //
    Do ..Transform(tOrigem, tDestino)
    //
    Write tDestino.StringValue, !
    Write !, "Teste da origem sendo um objeto dinâmico", !
    //
    Set tOrigem             = ##Class(%Object).%New()
    Set tOrigem.StringValue = "Origem dinâmico"
    Set tDestino            = ##Class(Ens.StringContainer).%New()
    //
    Do ..Transform(tOrigem, tDestino)
    //
    Write tDestino.StringValue, !
    Write !, "Teste da destino sendo um objeto dinâmico", !
    //
    Set tOrigem             = ##Class(Ens.StringContainer).%New()
    Set tOrigem.StringValue = "Destino dinâmico"
    Set tDestino            = ##Class(%Object).%New()
    //
    Do ..Transform(tOrigem, tDestino)
    //
    Write tDestino.StringValue, !
    Write !, "Teste ambos sendo um objeto dinâmico", !
    //
    Set tOrigem             = ##Class(%Object).%New()
    Set tOrigem.StringValue = "Ambos dinâmico"
    Set tDestino            = ##Class(%Object).%New()
    //
    Do ..Transform(tOrigem, tDestino)
    //
    Write tDestino.StringValue, !
}

}