NHibernate + Fluent :: Mapeamento de campo varchar com valor separado por caracter com conversão em propriedade de coleção no domínio automaticamente

Trabalhando em um projeto recente esbarrei na seguinte necessidade, um campo "varchar" na tabela XPTO possuirá conteúdo no seguinte formato:

65;78;21;6;98

É um caso bem conhecido, algo que em um banco de dados normalizado se transformaria em uma agregação, mas que nesse específico o conteúdo são as chaves estrangeiras para uma tabela separadas por ; (ou qualquer outro separador de valor) gravado em um campo na tabela.

A solução mais comum para esse tipo de caso seria tratar em um DTO, Model ou semelhante o retorno de uma propriedade com a coleção, um array por exemplo, após a leitura do campo que contém a lista concatenada. 

Usando Fluent e NHibernate (não testei sem Fluent) temos uma maneira mais direta e elegante de fazer o mesmo.



Na classe de mapeamento definimos a seguinte regra: 

Map(x => x.PropriedadeDaColecao"CampoComAListaConcatenada").CustomType(typeof(string)).Access.CamelCaseField(Prefix.Underscore);



Na classe de domínio a seguinte definição de propriedade:

        protected string _propriedadeDaColecao; 
        public virtual List<intPropriedadeDaColecao
        {
            get
            {
                if (string.IsNullOrEmpty(_propriedadeDaColecao))
                { 
                    return new List<int>();
                }
 
                return _propriedadeDaColecao.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries).Select(n => int.Parse(n)).ToList();
            }
            set
            {
                _propriedadeDaColecaostring.Join(";"value);
            }
        }


Apesar de mapearmos o campo "varchar" CampoComAListaConcatenada para a propriedade PropriedadeDaColecao, que é do "tipo coleção" - ao invés do tipo string como seria o correto - a definição do CustomType faz o que é necessário para se adequar ao domínio.

Uma explicação superficial é que através da definição ".Access.CamelCaseField(Prefix.Underscore)" o Fluent sabe que deve atribuir e recuperar o valor direto de _propriedadeDaColecao, que vemos que está declarada como "protected" ao invés de "private". A PropriedadeDaColecao será usada pelo programador de forma transparente como uma coleção.

É até natural a leitura do código, estamos dizendo que o CustomType é do tipo string, acessado através do "field" que está definido em CamelCase com o prefixo _ (underscore), ou seja, para PropriedadeDaColecao ele encontrará por Reflection _propriedadeDaColecao.


Uma outra possibilidade seria construirmos uma classe CustomType para o mapeamento, mas se temos essa possibilidade de conversão direta porque não usar?

Comentários

Postagens mais visitadas deste blog

Selenium + Firefox = The type initializer for 'System.IO.Compression.ZipStorer' threw an exception

Transmissor sem fio bluetooth Tomate MTB-803 e manual

Problema de rolagem de HTML em iframe no iOS