ASP.NET - Un método Select o Find genérico

 
Vista:

Un método Select o Find genérico

Publicado por Pableras (5 intervenciones) el 08/02/2007 11:51:18
Hola, qué tal ???

Estoy haciendo una aplicación de prueba usando la estructura que llaman de las "3 capas" (negocio, datos y presentación).

Si no sabes nada de lo de las "3 capas" casi mejor no sigas leyendo porque no me vas a entender.

Empiezo:

Tengo 2 tablas en mi pequeña aplicacación: Usuarios y Productos. En la primera aparecen los datos del usuario (nick, nombre, apellidos, fecha de nacimiento, etc) y en la segunda los productos comprados por este usuario (id, idProducto, nick, unidades, fechaCompra, horaCompra)

Resumiendo tengo estas tablas en la base de datos:

- Usuarios: Nick, Nombre, Apellidos, FechaNac.
- Productos: Id, IdProducto, Nick, Unidades, FechaCompra, HoraCompra (debería de haber una tabla, DatosProductos, que a través del IdProducto se relacionara con Productos, y nos diera todos los datos del producto en concreto: nombreProducto, precio, udsStock, etc, ... sería así: Usuarios - Productos - DatosProductos
, pero de momento no me hace falta para lo que quiero probar.)

Ambas tablas se relacionan por el nick (las tablas Usuarios y Productos digo).

Por otra parte, tengo en mi capa de negocio estos 2 cs's: BRUsuario.cs y BRProducto.cs.

En BRUsuario tengo los métodos SelectAll, Insert, Update con sus parámetros correspondientes (los que los necesiten). SelectAll selecciona todos los registros de la tabla Usuarios; Insert inserta un nuevo registro en la tabla y Update actualiza un registro.

La mismos métodos los tiene también el BRProducto, más el de SelectByNick(string nick)

Preguntas:

1) Si yo en una pantalla quiero mostrar los siguientes datos: Nombre, Apellidos, y más abajo la relación de los productos de ese usuario: IdProducto y Uds nada más (de la tabla Productos)??? Me tendría que crear otro "BR", llamémoslo BRMixto(por tener datos de ambas tablas) que tuviera los siguientes atributos: Nombre, Apellidos y un tercer campo que se llamase por ejemplo ProductosUsuario que fuera una colección de BRProducto's que se llenaría mediante new BRProducto.SelectByNick(nick) ??....no sé si me explico, para que en esta clase puedan desglosar todos los productos comprados por un usuario.

Sería algo así ???

2) Me gustaría encontrar una forma de no siempre traerme los mismos datos. Me explico: crear un método al que yo le pueda decir qué campos de cada tabla me quiero traer porque por ejemplo tengo el SelectAll en ambos BR's que traen todos los campos de sus respectivas tablas, pero para alguna pantalla en vez de traerme todos los campos sólo querré el nombre y apellidos (para BRUsuario) o el id del producto (para BRProducto), etc

Por ejemplo en la pregunta 1 me traía todos los productos mediante el new BRProducto.SelectByNick(nick), pero este método me trae todos los campos de Productos y sólo quiero el IdProducto y las Uds (para el ejemplo que ponía)

Había pensado algo así: un método Select (o Find,o Filter) en cada BR que fuera, por ejemplo, Select (campos a traer, filtro)...lo de "campos a traer" serían los campos que van después de un Select en una sentencia sql, y el "filtro" lo que va después del Where (nick='pepito',nombre='Jose', etc) ... algo así, que fuera un poco genérico y que cada vez que me quiero traer unos campos diferentes no tenga que crearme otro método.

Lo digo para no traerme información que no voy a necesitar (no traerme campos que no voy a utilizar)

Si tuvierais algún ejemplo que simplificase en un método esto que os cuento de las búsquedas os lo agradecería, y que fuese un poco "profesional", o alguna sugerencia vuestra para mi caso concreto.

3) Mi BRUsuario tiene estos atributos:

private DAUsuario _objDatos;
private string _id;
private string _nick;
private string _clave;
private bool _genero; // true=hombre

En la clase DAUsuario es donde hago todas las operaciones con bases de datos (capa de datos).

Sería lógico meter en un BR una referencia a otro BR ??? lo que comentaba antes: si después del atributo _genero añado otro que sea una colección de productos (new BRProducto.SelectByNick(_nick) ) .... sería correcto? o no es lógico llamar a una clase BR dentro de otra BR ??? a mí sí me lo parece pero no sé si se suele hacer así.

Agradecería cualquier tipo de documentación sobre cualquiera de estos apartados.

Muuuuuuuuuuchas gracias :-D
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Un método Select o Find genérico

Publicado por Pablo Iñareta (224 intervenciones) el 08/02/2007 15:20:09
te cuento lo q suelo hacer yo, que tb suelo programar en tres capa.
utilizo datasets tipados, es decir, creo datasets arrastrando las tablas segun las tengo en la base de datos.
en negocio me creo los metodos recuperar, normalmente 2, uno recupera todo y otro añade un "where" a la select, insertar borrar y editar, lo hago siempre con tadasets.
en datos me creo el acceso a datos puro y duro, una conexion, el metodo generico para recuperar cualquier tabla, y el metodo generico para hacer un update de cualquier tabla.
creo q es lo mas facil, recuperas datos datos q quizas no uses, pero si es asi, q mas da, con ignorarlos es suficiente.
la clase de datos me sirve para cualquier proyecto.
respecto a la clase de negocio me creo una clase para cada tabla, y ni que decir tiene, q dentro de la solucion tb me creo un proyecto con todos los datasets q necesite, tantos como clases en la capa-proyecto de negocio. puede parecer un lio pero no es asi, y una vez acostumbrado, lo haras todo asi.
en cualquier caso, mi capa de datos queda un poco coja en lo q se refiere a transacciones, pero ese es un problemilla q aun no he resuelto.
respecto a las clases o proyectos mixtos, donde realizas operaciones en varias tablas, esta bien, es algo q yo habia pensado para resolver el problemilla anterior usando clases transaccionales, pero no he tenido tiempo de probarlo. desde esta clase es desde donde se deberia llamas a las clases de negocio, y no instaciar una clase de negocio desde otra.
bueno, asi trabajo yo, sobretodo cuando lo hago por mi cuenta.
espero q te sirva o te de ideas
un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Un método Select o Find genérico

Publicado por Pableras (5 intervenciones) el 08/02/2007 18:49:09
Bueno, yo los datos que devuelvo cuando leo los devuelvo como una colección, en vez de un DataSet o DataTable's.

Este es el código que tengo para lectura de la tabla Usuarios:

----------------------------- DAUsuario.cs ------------------------------

public DAUsuariosColeccion SelectAll(IDbConnection cnn)
{
DAUsuariosColeccion col=new DAUsuariosColeccion();


try
{
if (cnn.State==ConnectionState.Closed)
cnn.Open();

IDbCommand cmd = cnn.CreateCommand();
cmd.CommandType=CommandType.Text;
cmd.CommandText="SELECT * FROM Usuarios";

IDataReader dr;
dr=cmd.ExecuteReader();

while (dr.Read())
{
BRUsuario user=new BRUsuario();

user.Nick=(dr["nick"].ToString()!=System.DBNull.Value.ToString())?Convert.ToString(dr["nick"]):"";
user.Genero=(dr["genero"].ToString()!=System.DBNull.Value.ToString())?true:false; // está mal puesta esta condición pero weno
user.Clave=(dr["clave"].ToString()!=System.DBNull.Value.ToString())?Convert.ToString(dr["clave"]):"";

col.Add(user);
}

}

catch(Exception ex)
{
throw ex;
}

return col;

}


public class DAUsuariosColeccion:System.Collections.CollectionBase
{
public void Add(BRUsuario newUser)
{
this.List.Add(newUser);
}

public BRUsuario this[int Index]
{
get
{
return (BRUsuario)this.List[Index];
}
}
}

------------------ BRUsuarios.cs ------------------

public BRUsuario(string nick,string clave,bool genero)
{
_objDatos=new DAUsuario();
_nick=nick;
_clave=clave;
_genero=genero;
}

public System.Collections.CollectionBase SelectAll(IDbConnection cnn)
{
return _objDatos.SelectAll(cnn);
}

----------------- En la página ------------------

BRUsuario user=new BRUsuario();

OleDbConnection cnn=new OleDbConnection(System.Configuration.ConfigurationSettings.AppSettings["OleDb_CnnString"]);

IEnumerator lista=user.SelectAll(cnn).GetEnumerator();

while (lista.MoveNext())
Response.Write("<br>" + ((BRUsuario)lista.Current).Nick + " " + ((BRUsuario)lista.Current).Genero + " " + ((BRUsuario)lista.Current).Clave);

-------------------------------------------------------

Voy leyendo usuarios de la base de datos y los voy metiendo en una colección. Luego voy recorriendo la lista y voy sacando los resultados.

Así no tengo DataSets en memoria ni nada.

De todas formas no controlo mucho lo de trabajar conectado y desconectado. Suelo utilizar siempre conexiones y commands. La verdad es que borrar,actualizar, etc dentro de un DataSet no estoy muy puesto y me gustaría aprender.

Lo que dices tú es, además del SelectAll tener un Select al que le pases lo que le corresponde del WHERE. Yo querría hacer eso, pero además de decirle las condiciones del Where, qué campos exactamente quiero que coja.

Tengo que ver cómo lo hago un poco elegante, no por dármelas de "guay" sino para intentar hacerlo lo más lógico y reutilizable posible.

Admito sugerencias !!!!!!! :-D
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Un método Select o Find genérico

Publicado por Pableras (5 intervenciones) el 08/02/2007 18:54:18
Se me olvidaba. Lo de devolver una colección está bien también porque igual que al DataSource de un DataGrid le puedes asignar un DataTable o lo que sea, también le puedes asignar una colección. Funciona perfectamente.

Lo dicho .... sugerenciassssss !!! :-D
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Un método Select o Find genérico

Publicado por Pablo Iñareta (224 intervenciones) el 08/02/2007 19:55:28
lo q trato de decirte es q con datasets, o por lo menos tal y como yo lo planteo, es reutilizable 100%, insisto, para accesos y actualizaciones sencillas.
Hay te va una funcion
Public Overridable Function recuperar(ByVal sTabla As String, ByVal ds As DataSet, Optional ByVal sWhere As String = "") As DataSet
Try
Dim sSql As String = "select * from " & sTabla & sWhere
Dim da As New SqlDataAdapter(sSql, Me.con)
da.Fill(ds, sTabla)
Me.con.Close()
Return ds
Catch ex As SqlException
Throw ex
Catch ex As Exception
Throw ex
Finally
If Me.con.State = ConnectionState.Open Then
Me.con.Close()
End If
End Try
End Function
Esta funcion me va a devolver siempre un dataset, de q tipo, pues del tipo que yo se lo mande. cuanto tardo en crear un dataset tipado, lo q tardo en arrastrar la tabla del origen de datos al nuevo dataset. comodo, sencillo, etc etc.

Public Overridable Function agregar(ByVal ds As DataSet) As Integer

Try
Dim sSql As String = "select * from " & ds.Tables(0).TableName
Dim da As New SqlDataAdapter(sSql, Me.con)

da.FillSchema(ds, SchemaType.Mapped, ds.Tables(0).TableName)
Dim cb As New SqlCommandBuilder(da)

da.InsertCommand = cb.GetInsertCommand
da.UpdateCommand = cb.GetUpdateCommand
da.DeleteCommand = cb.GetDeleteCommand

da.Update(ds, ds.Tables(0).TableName)

'da.TableM()
Me.con.Close()

ds = Me.recuperar(ds.Tables(0).TableName, ds)
Dim fila As DataRow
fila = ds.Tables(0).Rows(ds.Tables(0).Rows.Count - 1)
Return fila.Item(0)

Catch ex As Exception
Throw ex
Finally
If Me.con.State = ConnectionState.Open Then
Me.con.Close()
End If
End Try
End Function
lo mismo, me hace la actualizacion q sea. es casi de libro, lo q ocurre q yo, o bien le paso la nueva fila, o la fila editada, o la fila a borrar, siempre de uno en uno. no es de libro pq de libro seria llenar primero el datase, y luego operar con las filas, pero como lo q yo le paso es el dato modificado, ejecuta igual la actualizacion, si lees un poco sobre datasets sabras lo q digo.
estas funciones son la base de mi acceso a datos de mis aplicaciones "sencillas", son perfeccionables, pero ando muy mal de tiempo.
a los command se les puede añadir parametros, etc, pero ya hay q ir al evento onRowUpdated y pillar la fila actualizada etc etc, pero vamos que estoy seguro q se puede completar mucho mas y siempre parametrizable.
y nada mas, siento q te estoy metiendo un rollo impresionante
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Un método Select o Find genérico

Publicado por Capa de Datos (2 intervenciones) el 04/08/2007 21:57:25
http://dummycode.blogspot.com/
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar