Cómo crear una búsqueda dinámica con linq, la típica con where dinámico

 

¿Cómo se podría hacer con Dlinq el típico formulario de búsqueda por varios campos?

Muy fácil, se puede formar dinámicamente la consulta, al estilo procedimiento almacenado, pero todo desde Visual Studio, depurando y de una forma directa. Creo que realmente esto es un gran progreso respecto a como se realizaba anteriormente, ahí no hay conexiones, entlib.. ni nada por el estilo, se ataca la base de datos de una forma muy directa.

 

 

 

Código del botón buscar de la web (los cb son combos y los tb textbox):

protected void btBuscar_Click(object sender, EventArgs e)
{
var q = from p in db.PROYECTOS
from t in db.TRABAJOS
from pri in db.PRIORIDADES
from est in db.ESTADOS
where p.PROTRABAJO==t.TRAID && p.PROPRIORIDAD==pri.PRIID && p.PROESTADO==est.ESTID
select new{proexpediente=p.PROEXPEDIENTE,protrabajo=t.TRANOMBRE, prodescripcion=p.PRODESCRIPCION,
PRIORIDAD=pri.PRINOMBRE,ESTADO=est.ESTNOMBRE,
CLIID=p.CLIID,PROEXPEDIENTE=p.PROEXPEDIENTE,PRONUMVIVIENDAS=p.PRONUMVIVIENDAS,
LOCID=p.LOCID,CORID=p.CORID,PROFECHAALTA=p.PROFECHAALTA,PROESTADO=p.PROESTADO,PROID=p.PROID};

if (cbClientes.SelectedValue != "0")
{
q = q.Where(h=> h.CLIID == Convert.ToInt32(cbClientes.SelectedValue));
}
if (!string.IsNullOrEmpty(tbExpediente.Text))
{
q = q.Where(h=> h.PROEXPEDIENTE == tbExpediente.Text);
}
if (tbNumViviendas.Text != "0")
{
q = q.Where(h=> h.PRONUMVIVIENDAS == Convert.ToInt32(tbNumViviendas.Text));
}
if (cbLocalidades.SelectedValue != "0")
{
q = q.Where(h=> h.LOCID == Convert.ToInt32(cbLocalidades.SelectedValue));
}
if(cbCoordinador.SelectedValue!="0")
{
q = q.Where(h=> h.CORID == Convert.ToInt32(cbCoordinador.SelectedValue));
}
if(cbAño.SelectedValue!="0")
{
q = q.Where(h=> h.PROFECHAALTA.Year.ToString()== cbAño.SelectedValue);
}
if(!chboxIncluirTerminados.Checked)
{
q = q.Where(h=> h.PROESTADO != 2);
}

GridViewBuscados.DataSource = q;
GridViewBuscados.DataBind();  <– Aquí ejecuta la consulta en la BBDD
}

 

Todo esto forma un sql muy correcto:

exec sp_executesql N’SELECT [t0].[PRO_EXPEDIENTE] AS [proexpediente], [t1].[TRA_NOMBRE] AS [protrabajo], [t0].[PRO_DESCRIPCION] AS [prodescripcion], [t2].[PRI_NOMBRE] AS [PRIORIDAD], [t3].[EST_NOMBRE] AS [ESTADO], [t0].[CLI_ID] AS [CLIID], [t0].[PRO_NUM_VIVIENDAS] AS [PRONUMVIVIENDAS], [t0].[LOC_ID] AS [LOCID], [t0].[COR_ID] AS [CORID], [t0].[PRO_FECHA_ALTA] AS [PROFECHAALTA], [t0].[PRO_ESTADO] AS [PROESTADO], [t0].[PRO_ID] AS [PROID]
FROM [PROYECTOS] AS [t0], [TRABAJOS] AS [t1], [PRIORIDADES] AS [t2], [ESTADOS] AS [t3]
WHERE ([t0].[PRO_ESTADO] <> @p0) AND ([t0].[PRO_TRABAJO] = [t1].[TRA_ID]) AND ([t0].[PRO_PRIORIDAD] = [t2].[PRI_ID]) AND ([t0].[PRO_ESTADO] = [t3].[EST_ID])’,N’@p0 int’,@p0=2

 

El linq realmente va a cambiar la forma de hacer los programas….

Advertisements

4 comments

  1. Korzario · · Reply

    Gracias amigo, pero esto esta malo
    cuando hacemos esto

    if (cbClientes.SelectedValue != “0”)
    {
    q = q.Where(h=> h.CLIID == Convert.ToInt32(cbClientes.SelectedValue));
    }

    nos traemos solamente los que cumplen este criterio de busqueda
    dejamos en q solo una parte de los datos
    si luego hacemos esto

    if (!string.IsNullOrEmpty(tbExpediente.Text))
    {
    q = q.Where(h=> h.PROEXPEDIENTE == tbExpediente.Text);
    }
    estamos buscando con los datos ya acotados, por lo que nos queda informacion por
    fuera de la consulta.

    Esto no sirve, pues vamos trabajando con los datos que cumplen un criterio, y a esos datos les aplicamos otro criterio.

    Creo que se deberia hacer una busqueda por cada uno de los criterios, y luego hacer una especie de join, para que tengamos el conjunto completo de datos.

    😀 gracias.

    1. Creo que no he entendido el problema que ves. La consulta se lanza cuando hacemos el databind, por lo tanto se van añadiendo todo los wheres que aplican, que efectivamente acotan unos a otros, pero esa es la intención, no?

  2. ¿Y cual es la sintaxis para aplicar un OR complejo de este estilo?
    if check1.checked then
    sql = sql & ” And (vende=’juan’ or compra=’pedro’)
    else
    sql = sql & ” And ((atiende=’juan2′ or jefe=’tomas’) and usuario=’ramiro’)
    end if

    No os quedeis con esta SQL, sino pensad cualquier otro ejmplo con OR y AND combinados.

  3. Marcelo · · Reply

    Pablo…la consulta a la base de datos se realiza cuando seteas la variable “q” y no como decis q al hacer el Databind de la grilla, ya q ese metodo solo enlaza los controles con un origen de datos obtenidos previamente.
    Es mas si no haces el databind la variable “q” tiene los datos igual, hace un debug de ese metodo antes de setear el datasource y veras lo que te comento. Saludos.
    Saludos

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: