1. Conexión a la base de datos desde
Visual Studio y la arquitectura
Modelo Vista Controlador (MVC)
En esta práctica, estudiaremos como realizar la conexión a la base de datos desde una
aplicación en C#. Después usando lo aprendido, crearemos una pequeña aplicación que
interactúe con la base de datos usando un patrón arquitectónico llamado Modelo Vista
Controlador.
Antes de todo:
Primeramente, debemos tener una base de datos donde trabajar. Para esto, inicie el SQL
Managment Studio.
Abra el script proporcionado, y ejecútelo, al final debería tener una base de datos equivalente
a esta:
2. Conexión a la base de datos desde C#
Ahora intentaremos realizar la conexión desde una aplicación en C# a la base de datos, para
esto, usaremos una tecnología de la plataforma .NET, llamada ADO.NET, que significa ActiveX
Data Object, para usar la tecnología y conectarse a la base de datos realice los siguientes
pasos:
1. Ingrese a Visual Studio
2. Cree un proyecto en Consola para C#
3. Dentro del método Main introduzca el siguiente código:
static void Main(string[] args)
{
string connectionString = "server=.SQLEXPRESS;" +
4. Antes de ejecutar el código, observe la cadena de conexión. La cadena de conexión es
un equivalente a la URL. En esta cadena uno debe indicar donde esta el servidor de la
base de datos, y el nombre de la base de datos a acceder. Dependiendo como es la
instalación de su servidor, la cadena de conexión puede variar. En el campo “server”,
puede venir los siguientes ejemplos
a. .SLQEXPRESS
"integrated security=SSPI;" +
"database=Universidad";
string sql = "SELECT TOP 10 nombre, apellido FROM Alumno";
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlCommand command = new SqlCommand(sql, conn);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("{0}tt{1}", reader[0], reader[1]);
}
conn.Close();
}
3. b. .MSSQLSERVER
c. Nompre-PCSQLEXPRESS
d. .NombreInstancia
5. En el campo database debe estar el nombre de la base de datos a acceder.
6. Edite la cadena de conexión dependiendo como se acopla a su caso.
7. Ejecute el programa.
Responda las siguientes preguntas
1. Que hace el programa?
2. Que cree que hace el objeto SqlConnection?
3. Que cree que hace el objeto SqlCommand?
4. Que cree que hace el objeto SqlDataReader?
Arquitectura Modelo Vista Controlador
En el desarrollo de software existen los patrones arquitectónicos, modelos de diseño de
software que permiten organizar mejor las clases y objetos de tal manera de crear programas
con un buen diseño orientado a objetos. Uno de estos patrones se denomina el patrón
Modelo Vista Controlador (MVC). Este patrón es usado bastante en el mundo del desarrollo de
software. Muchos frameworks en varios lenguajes fueron desarrollados siguiendo esta
arquitectura. Ejemplos de esto son:
· ASP.NET MVC
· Ruby on Rails
· Java Server Faces
La idea de esta arquitectura, es separar las responsabilidades de las clases y dividirlos en
capas. Existe un objeto llamado el modelo. Que se ocupa de mantener la lógica de validación y
que los objetos en el programa se mantengan en un estado consciente. Como parte del
modelo, existe el manejo de los datos. Y como guardarlos por ejemplo en una base de datos, o
en un archivo, dependiendo los requerimientos del sistema.
Después del modelo. Tenemos las vistas. Estos objetos pertenecientes a la vista se ocupan de
mostrar los datos de alguna manera al usuario. La idea de la arquitectura Modelo Vista
Controlador es que fácilmente podamos cambiar las vistas. Por ejemplo de tener una vista que
esta en Windows Forms, a una vista manejado como sistema web en ASP.NET o en consola.
Al final existe una clase, llamada Controlador, que es la que se encarga de comunicar a la Vista
con el Modelo. Este se encarga de mandar mensajes al modelo para que se actualice y los
resultados mandarlos a la Vista, para que el usuario puede ver los resultados.
En esa clase, se mostrara una implementación básica de la arquitectura Modelo Vista
Controlador.
Empecemos a implementar.
Antes de todo, se supone que dentro de su servidor SQLServer ya ejecuto el script
proporcionado y tiene una base de datos llamada Universidad.
4. 1. Cree un proyecto de Windows Forms
2. Dentro de este proyecto cree las siguientes carpetas
a. Model
b. View
c. Controller
d. Database
3. Dentro de la carpeta Model cree una clase llamada Student, y una clase llamada
ModelException
4. En la clase ModelException introduzca el siguiente código:
public class ModelException : Exception
{
public ModelException(string msg)
: base(msg) {}
}
5. 5. En la clase Student introduzca el siguiente código:
public class Student
{
private int ci;
private string firstName;
private string lastName;
private DateTime birthday;
private int cellphone;
public Student()
{
ci = 0;
firstName = "";
lastName = "";
birthday = DateTime.Now;
cellphone = 71234567;
}
public int CI {
get
{
return ci;
}
set
{
if (value < 100000)
throw new ModelException("El CI no es válido");
ci = value;
}
}
public string FirstName
{
get
{
return firstName;
}
set
{
6. if (String.IsNullOrEmpty(value))
throw new ModelException("El nombre no puede estar vacio");
if (value.Length > 30)
throw new ModelException("El nombre no puede tener mas de 30
carácteres");
firstName = value;
}
}
public string LastName
{
get
{
return lastName;
}
set
{
if (String.IsNullOrEmpty(value))
throw new ModelException("El apellido no puede estar
vacio");
if (value.Length > 30)
throw new ModelException("El apellido no puede tener mas de
30 carácteres");
lastName = value;
}
}
public DateTime Birthday
{
get
{
return birthday;
}
set
{
if (value > DateTime.Now)
throw new ModelException("La fecha de nacimiento aun no
pasó!!");
birthday = value;
}
}
public int CellPhone
{
get
{
return cellphone;
}
set
{
if (value < 60000000 || value > 80000000)
throw new ModelException("Celular no valido");
cellphone = value;
}
}
}
7. 6. Antes de seguir. Revise y estudie el código y responda las siguientes preguntas:
a. Que representa la clase Student?
b. Que se hace en las funciones set/get de la clase?
c. Como se reporta errores en el modelo?
7. Dentro de la carpeta cree una clase llamada ConnectionManager. La responsabilidad
de esta clase será la encargada de mantener la cadena de conexión, Conectarse a la
base de datos y dar una manera de ejecutar comandos SQL a las otras clases. La clase
es como sigue:
public class ConnectionManager : IDisposable
{
private string connectionString = "server=.SQLEXPRESS;" +
8. Antes de continuar, responda, los objetos usados en esta clase le parecen familiar?
9. Cree una clase DatabaseException. El código de la clase sigue asi:
public class DatabaseException : Exception
{
public DatabaseException(string message) :
base(message) { }
}
10. Cree una clase dentro de la carpeta Database llamada StudentsDatabase, el código de
la clase es como sigue:
"integrated security=SSPI;" +
"database=Universidad";
private SqlConnection connection;
public ConnectionManager()
{
connection = new SqlConnection(connectionString);
connection.Open();
}
public SqlCommand GetCommand(string sql)
{
return new SqlCommand(sql, connection);
}
public void Dispose()
{
connection.Close();
connection.Dispose();
}
8. public class StudentsDatabase : IDisposable
{
private ConnectionManager connection;
public StudentsDatabase()
{
connection = new ConnectionManager();
}
public Student GetUserByCI(int CI)
{
try
{
String sql = "SELECT * FROM Alumno WHERE CI = @CI";
SqlCommand command = connection.GetCommand(sql);
command.Parameters.AddWithValue("@CI", CI);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
Student student = new Student
{
CI = Convert.ToInt32(reader[0]),
FirstName = Convert.ToString(reader[1]),
LastName = Convert.ToString(reader[2]),
Birthday = Convert.ToDateTime(reader[3]),
CellPhone = Convert.ToInt32(reader[4])
};
reader.Close();
return student;
}
reader.Close();
}
catch (Exception exception)
{
throw new DatabaseException("Error en la base de datos: " +
exception.Message);
}
return null;
}
public void CreateNewStudent(Student student)
{
try
{
String sql = "INSERT INTO Alumno (CI, nombre, apellido, fechanac,
celular) " +
"VALUES (@CI, @firstname, @lastname, @birthday,
@cellphone)";
SqlCommand command = connection.GetCommand(sql);
command.Parameters.AddWithValue("@CI", student.CI);
command.Parameters.AddWithValue("@firstname", student.FirstName);
command.Parameters.AddWithValue("@lastname", student.LastName);
command.Parameters.AddWithValue("@birthday", student.Birthday);
command.Parameters.AddWithValue("@cellphone", student.CellPhone);
9. int rows = command.ExecuteNonQuery();
if (rows == 0)
throw new DatabaseException("Error en la base de datos");
}
catch (Exception exception)
{
throw new DatabaseException("Error en la base de datos: " +
exception.Message);
}
}
public void UpdateStudent(Student student)
{
try
{
String sql = "UPDATE Alumno SET" +
"nombre = @firstname, " +
"apellido = @lastname, " +
"fechanac = @fechanac, " +
"celular = @cellphone " +
"WHERE CI = @CI";
SqlCommand command = connection.GetCommand(sql);
command.Parameters.AddWithValue("@CI", student.CI);
command.Parameters.AddWithValue("@firstname", student.FirstName);
command.Parameters.AddWithValue("@lastname", student.LastName);
command.Parameters.AddWithValue("@birthday", student.Birthday);
command.Parameters.AddWithValue("@cellphone", student.CellPhone);
int rows = command.ExecuteNonQuery();
if (rows == 0)
throw new DatabaseException("Error en la base de datos");
}
catch (Exception exception)
{
throw new DatabaseException("Error en la base de datos: " +
exception.Message);
}
}
public void DeleteStudentByCI(int CI)
{
try
{
String sql = "DELETE FROM Alumno " +
"WHERE CI = @CI";
SqlCommand command = connection.GetCommand(sql);
command.Parameters.AddWithValue("@CI", CI);
int rows = command.ExecuteNonQuery();
if (rows == 0)
throw new DatabaseException("Error en la base de datos");
}
catch (Exception exception)
{
throw new DatabaseException("Error en la base de datos: " +
exception.Message);
}
}
10. public List<Student> GetAllStudents()
{
List<Student> students = new List<Student>();
try
{
String sql = "SELECT * FROM Alumno";
SqlCommand command = connection.GetCommand(sql);
SqlDataReader reader = command.ExecuteReader();
while(reader.Read())
{
11. Deténgase en esta clase, analice el código y responda las siguientes preguntas:
a. Que responsabilidades tiene esta clase?
b. Que hace cada método de la clase?
c. Como se ejecutan las sentencias SQL?
d. Como se reportan errores de la base de datos al programa?
e. Como se busca un objeto en la base de datos?
f. Como se inserta un nuevo objeto en la base de datos?
g. Como se elimina un objeto en la base de datos?
h. Como se edita un objeto en la base de datos?
i. Investigue un poco mas acerca de las sentencias SQL preparadas. Que ventajas
tiene usar este tipo de sentencias? Ve alguna sentencia SQL Preparada en esta
clase?
12. En la carpeta View cree una carpeta llamada Student, dentro de este cree los
siguientes formularios:
Student student = new Student
{
CI = Convert.ToInt32(reader[0]),
FirstName = Convert.ToString(reader[1]),
LastName = Convert.ToString(reader[2]),
Birthday = Convert.ToDateTime(reader[3]),
CellPhone = Convert.ToInt32(reader[4])
};
students.Add(student);
}
}
catch (Exception exception)
{
throw new DatabaseException("Error en la base de datos: " +
exception.Message);
}
return students;
}
public void Dispose()
{
connection.Dispose();
}
}
12. c. ShowStudentForm
d. EditStudentForm
13. En los formularios de, Editar Alumno, Buscar Alumno y Registrar Alumno cree los
siguientes métodos (Cambie el nombre de los objetos dependiendo como usted llamo
a sus controles al crear los formularios):
13. public (Nombre_Constructor)(StudentController theController)
{
InitializeComponent();
controller = theController;
}
public String CI
{
get
{
return ciTextBox.Text;
}
set
{
ciTextBox.Text = value;
}
}
public String FirstName
{
get
{
return firstNameTextBox.Text;
}
set
{
firstNameTextBox.Text = value;
}
}
public String LastName
{
get
{
return lastNameTextBox.Text;
}
set
{
lastNameTextBox.Text = value;
}
}
public String BirthDay
{
get
{
return birthdayDate.Text;
}
set
{
birthdayDate.Text = value;
}
}
14. public String Cellphone
14. Cree una clase dentro de la carpeta Controller una clase llamada StudentController, el
código de la clase es como sigue:
public class StudentController : IDisposable
{
private StudentMenu studentMenu;
private StudentsDatabase model;
public StudentController(StudentMenu menu)
{
studentMenu = menu;
model = new StudentsDatabase();
}
public void ShowRegisterStudent()
{
studentMenu.Hide();
RegisterStudentForm register = new RegisterStudentForm(this);
register.Show();
}
public void RegisterStudent(RegisterStudentForm registerForm)
{
try
{
Student student = new Student();
student.CI = Convert.ToInt32(registerForm.CI);
student.FirstName = registerForm.FirstName;
student.LastName = registerForm.LastName;
student.Birthday = Convert.ToDateTime(registerForm.BirthDay);
student.CellPhone = Convert.ToInt32(registerForm.Cellphone);
if (model.GetUserByCI(student.CI) != null)
{
throw new Exception("El Estudiante ya ha sido registrado");
}
{
get
{
return cellphoneTextBox.Text;
}
set
{
cellphoneTextBox.Text = value;
}
}
public void ShowError(String message)
{
MessageBox.Show(message, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
15. model.CreateNewStudent(student);
registerForm.Hide();
registerForm.Dispose();
studentMenu.Show();
}
catch (Exception ex)
{
registerForm.ShowError(ex.Message);
}
}
public void Dispose()
{
model.Dispose();
}
}
15. Dentro del formulario StudentMenu, edite el código e introduzca el siguiente código:
private StudentController controller;
private PrincipalMenu principal;
public StudentMenu(PrincipalMenu principalMenu)
{
InitializeComponent();
controller = new StudentController(this);
principal = principalMenu;
}
16. Haga doble click en el botón Registrar Alumno, en el evento generado introduzca el
siguiente código:
controller.ShowRegisterStudent();
17. En el formulario de Registrar Alumno, en el botón registrar, haga doble click, ejecute el
siguiente código:
controller.RegisterStudent(this);
16. 18. En el formulario creado por defecto en el proyecto, renómbrelo por PrincipalMenu,
coloque controles, este se tiene que ver de la siguiente manera:
19. Haga doble click en el botón Alumnos, introduzca el siguiente código:
StudentMenu menu = new StudentMenu(this);
menu.Show();
Hide();
20. Haga doble click en el botón Salir, introduzca el siguiente código:
Application.Exit();
21. En el formulario StudentMenu, haga doble click en el botón Volver e introduzca el
siguiente código:
principal.Show();
Hide();
controller.Dispose();
Dispose();
22. Ejecute el programa
23. Responda las siguientes preguntas:
a. Que hace el controlador?
b. Que hacen las vistas?
c. Que ventajas ve usted al separar las responsabilidades en distintas clases?
d. Que desventajas ve usted al separar las responsabilidades en distintas clases?
e. Cual es el objetivo de crear métodos set/get en las vistas?
f. Donde se muestran los errores reportados por todas las clases creadas?
24. Pruebe el programa
25. Intente completar el “modulo” de Alumnos, implementando el buscar, editar y
eliminar. Las vistas ya están creadas, El modelo ya esta listo, complete el controlador y
los eventos necesarios de las vistas.
26. Intente implementar el “modulo” Materias.
17. Entrega
La práctica debe ser entregada de la siguiente manera:
El código completo de la practica, un archivo en Word con las respuestas de las preguntas de la
practica, propiamente nombradas, en un archivo comprimido de la siguiente manera:
PracticaV-(nombrecompleto).rar
El archivo comprimido enviarlo al correo inf151ucb@gmail.com con el asunto PrácticaIX-
(nombre completo). Entregar el trabajo hasta las 23:59 del día 4 de noviembre del año 2013.
* Si se detecta copia, el trabajo será anulado para el que copió y el que hizo copiar.
* Este trabajo será evaluado como parte de la evaluación continua