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<int> PropriedadeDaColecao
{
get
{
if (string.IsNullOrEmpty(_propriedadeDaColecao))
{
return new List<int>();
}
return _propriedadeDaColecao.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries).Select(n => int.Parse(n)).ToList();
}
set
{
_propriedadeDaColecao= string.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
Postar um comentário