Yamapper: objeto Criteria
Em Yamapper | 13/01/2012 15:09
O objeto Criteria é o cerne de todas as ações de filtragem de dados no Yamapper. A ideia é permitir uma maneira simples e orientada a objetos de definição de restrições para obtenções de dados independente de qual gerenciador de banco de dados esteja em utilização.
Utilização
Os métodos de obtenção (Get), exclusão (Delete), checagem de existência (Exists) e contagem de registros (Count) do objeto DbProvider podem receber como parâmetro um objeto Criteria para filtragem dos dados, como no exemplo abaixo:
provider.Get<Cliente>(Criteria.Create()
.Add(Expression.Equal("IdCliente", idCliente)));
De modo geral, para utilização do objeto Criteria, obtenha sua instância a partir do método Create e adicione expressões de filtragem, ordenação e limitação de quantidade de registros a partir de seus métodos públicos:
Add: adiciona uma nova expressão de filtragem;AddOrder: adiciona um novo campo para ordenação;Offset: define a posição do registro inicial para obtenção de dados (começa em 0);Limit: define a quantidade máxima de registros a serem retornados.
O uso do objeto Criteria é recursivo, sendo que seus métodos sempre retornam sua instância atual para facilitar o aninhamento de expressões.
Expressões
Expressões são objetos que definem parâmetros de filtragem de dados no objeto Criteria. Para instanciá-las, utilize a factory Expression, a qual permite a criação de todos os tipos de expressões disponíveis.
Expressões simples
Expressões simples (geradas a partir do objeto SimpleExpression) permitem a realização de filtragens envolvendo os operadores de comparação básicos. A maioria dos métodos para criação dessas expressões recebem como parâmetro o campo que se deseja avaliar e o dado de comparação.
Equal: igualdade;NotEqual: desigualdade;GreaterThan: maior que;GreaterOrEqual: maior ou igual que;LesserThan: menor que;LesserOrEqual: menor ou igual que;IsNull: verificação de um campo nulo;IsNotNull: verificação de um campo não nulo;Like: comparação por parte de string;NotLike: comparação por parte de string de forma negativa;Between: comparação entre dois valores.
Expressões In e NotIn
As expressões In e NotIn permitem a comparação de um campo a um conjunto de valores. Ambas são métodos genéricos que devem receber o tipo do vetor de objetos o qual contém os dados a serem utilizados na filtragem.
provider.Get(Criteria.Create()
.Add(Expression.In<string>("Nome"
, new string[] { "Astrobaldo", "Bráulio", "Josisbaldo" })));
Expressões SQL
Expressões SQL permitem o envio de códigos SQL diretamente como parâmetro de filtragem, os quais serão anexados diretamente à clausula WHERE da instrução enviada ao banco de dados. Sua utilização pode ser feita com ou sem parâmetro. Caso haja parâmetro, a palavra reservada {param} deverá ser utilizada para indicar o local no qual deverá ser substituído o nome interno do parâmetro gerado. No exemplo abaixo, são retornados todas as pessoas que possuam nomes com a letra J:
provider.Get(Criteria.Create()
.Add(Expression.Sql("Nome LIKE {param}", "%J%")));
Expressões lógicas
O uso de expressões lógicas permite o aninhamento de diversas expressões a partir de operadores lógicos, auxiliando na composição de filtragens mais complexas. Para utilizá-las, basta utilizar os métodos Expression.And ou Expression.Or, de acordo com o operador lógico desejado, para criar e aninhar expressões. A quantidade de expressões que pode ser aninhada é ilimitada. No exemplo abaixo, expressões AND são aninhadas em uma expressão OR para obtenção de registros de pessoas com determinados nomes e configurações de data:
provider.Get(Criteria.Create()
.Add(Expression.Or(
Expression.And(
Expression.Equal("Nome", "Astrobaldo"),
Expression.IsNull("DataCadastro"))
, Expression.And(
Expression.Equal("Nome", "Bráulio"),
Expression.IsNotNull("DataCadastro"))
, Expression.And(
Expression.Equal("Nome", "Josisbaldo"),
Expression.LesserThan("DataCadastro", DateTime.Now))
)
)
);
Criando suas próprias expressões
Para criar suas próprias expressões, basta programar uma classe que implemente a interface Intentor.Yamapper.IExpression, a qual possui um único método, string ToSqlString<T>(string parameterPrefix, List, o qual deve ser utilizado para obter a expressão em formato SQL, preferencialmente independente de particularidades de um determinado banco de dados.
Paginação
A partir do uso do objeto Criteria é possível realizar paginação de dados através dos métodos Limit (quantidade máxima de registros a ser retornada) e Offset (índice do registro inicial para obtenção dos dados, começando em 0). O exemplo abaixo demonstra a utilização de tal procedimento em um método PageIndexChanging de um GridView:
protected void gvClientes_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
//Obtém o GridView.
var grv = ((GridView)sender);
//Obtém o tamanho da página para paginação.
int pageSize = grv.PageSize;
//Cria o critério de paginação utilizando-se de OffSet e Limit.
var crit = Criteria.Create()
.Offset(e.NewPageIndex * pageSize) //Posição inicial.
.Limit(pageSize); //Quantidade máxima de registros a ser obtida.
//Popula o GridView.
grv.PageIndex = e.NewPageIndex;
grv.DataSource = Facade.GetByCriteria(crit)
.BindTo<ClienteView, Cliente>();
grv.DataBind();
}
Adicionalmente, pode-se também criar uma classe que, a partir do uso dos mesmos métodos, permita a paginação de dados:
public class ClientesDataSource
{
private ClienteBiz _biz = new ClienteBiz(new ClienteDao());
public int SelectCount()
{
return _biz.Count();
}
public List<ClienteView> Select(int maximumRows, int startRowIndex)
{
return _biz.GetByCriteria(Criteria.Create()
.Offset(startRowIndex)
.Limit(maximumRows)
).BindTo<ClienteView, Cliente>();
}
}
Para utilizá-la, crie um ObjectDataSource na página e vincule-o ao GridView, como no exemplo abaixo:
<asp:GridView ID="gvClientes" runat="server" DataSourceID="odsClientes" AllowPaging="True" PageSize="5" AutoGenerateColumns="false"> <Columns> <asp:BoundField DataField="Nome" HeaderText="Cliente" /> </Columns> </asp:GridView> <asp:ObjectDataSource ID="odsClientes" runat="server" EnablePaging="True" TypeName="Intentor.Examples.Web.ClientesDataSource" SelectMethod="Select" SelectCountMethod="SelectCount"> </asp:ObjectDataSource>
NOTA: o uso do extension method BindTo e um DataTransferObject se fazem necessários caso a classe que representa a entidade utilize LazyLoading, uma vez que o GridView tem problemas em interpretar corretamente proxy classes via Reflection
Ao infinito e além
O projeto de exemplo presente no código-fonte do Yamapper apresenta o uso do objeto Criteria de forma prática, reunindo diversos exemplos de sua utilização.
Caso tenha alguma dúvida, curiosidade, trauma ou angústia sobre o projeto, ou apenas deseja elogiá-lo, utilize o espaço de comentários mais abaixo para entrar em contato.
Yamapper evoluindo a passos largos e com uma leveza e simplicidade surpreendente...!!!! Parabéns!!
ResponderValeu, Mr. Anderson! De fato, leveza e simplicidade sempre foram os focos do projeto!
Responder