De vorige keer hebben we de generieke Data Layer interface gebouwd. We gaan dit keer verder met het bouwen van een concrete implementatie van de Data Layer, namelijk voor SqlServer.
Om te beginnen voeg eerst een paar references toe aan de class library OrderSystem.DataLayer.SqlServer. Klik met de rechtermuisknop op de hiervoorgenoemde class library. Kies Add Reference-> Tabblad Projects -> Kies het project OrderSystem.DataLayer. Doe hetzelfde nog een keer voor OrderSystem.BusinessLayer.BusinessObjects en ook nog een keer voor System.Configuration in het tabblad .NET.
In de concrete implementatie van de Data Layer hoeven we alleen de Data Access Objects (DAO) en de DaoFactory te implementeren. In het OrderSystem is maar sprake van 1 DAO, namelijk OrderDao. In de OrderSystem.DataLayer hebben we hiervoor een interface gebouwd. Deze interface gaan we nu implementeren.
We gaan werken met SqlServer. Om data uit de database te halen worden er SQL-queries gebruikt. We willen deze queries niet graag hard-coded in de code hebben, omdat onderhoudsintensief is als er ooit een keer iets veranderd wordt in de database. We kunnen dit redelijk eenvoudig oplossen door een resource file te gebruiken.
Klik met de rechtermuisknop op de OrderSystem.DataLayer.SqlServer class library. Kies Add -> New Item -> Resources File. We noemen deze resources file OrderDaoQueries. In deze file kunnen we elke querie een unieke naam geven een aanroepen in de code. Dus “select * from orders” geven we de naam GetOrders. In code kunnen we dan het volgende aanroepen:
OrderDaoQueries.GetOrders
Op deze manier hebben we niet de queries zelf in de code staan.
Klik met de rechtermuisknop op de OrderSystem.DataLayer.SqlServer class library. Kies Add-> Class… Geef de class de naam OrderDao. De inhoud van de class ziet er als volgt uit:
using System.Collections.Generic; using System.Text; using OrderSystem.BusinessLayer.BusinessObjects; using System.Data.SqlClient; using System.Configuration; using System.Data; using OrderSystem.Framework.Transactions; namespace OrderSystem.DataLayer.SqlServer { /// /// SqlServer specific data access object that handles data access /// of customer related orders and order details. /// Enterprise Design Pattern: Service Stub. /// public class OrderDao : IOrderDao { #region IOrderDao Members public Order GetOrder(int orderID) { Order order = null; string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.GetOrder; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("ID", orderID); try { connection.Open(); using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { order = new Order(); order.ID = reader.GetInt32(reader.GetOrdinal("ID")); order.KlantNaam = reader.GetString(reader.GetOrdinal("KlantNaam")); order.OrderDatum = reader.GetDateTime(reader.GetOrdinal("OrderDatum")); order.Status = reader.GetString(reader.GetOrdinal("Status")); order.OrderDetails = GetOrderDetails(order); } } } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } return order; } public IList GetOrders() { IList orders = new List(); string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.GetOrders; command.CommandType = CommandType.Text; try { connection.Open(); using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Order order = new Order(); order.ID = reader.GetInt32(reader.GetOrdinal("ID")); order.KlantNaam = reader.GetString(reader.GetOrdinal("KlantNaam")); order.OrderDatum = reader.GetDateTime(reader.GetOrdinal("OrderDatum")); order.Status = reader.GetString(reader.GetOrdinal("Status")); orders.Add(order); } } } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } return orders; } public IList GetOrderDetails(Order order) { IList orderDetails = new List(); string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.GetOrderDetails; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("OrderID", order.ID); try { connection.Open(); using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { OrderDetail orderDetail = new OrderDetail(); orderDetail.ID = reader.GetInt32(reader.GetOrdinal("ID")); orderDetail.Aantal = reader.GetDecimal(reader.GetOrdinal("Aantal")); orderDetail.Bedrag = reader.GetDecimal(reader.GetOrdinal("Bedrag")); orderDetail.Eenheid = reader.GetString(reader.GetOrdinal("Eenheid")); orderDetail.Omschrijving = reader.GetString(reader.GetOrdinal("Omschrijving")); orderDetail.StukPrijs = reader.GetDecimal(reader.GetOrdinal("StukPrijs")); orderDetails.Add(orderDetail); } } } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } // bind the OrderDetail list to the order order.OrderDetails = orderDetails; return orderDetails; } public void VoegOrderToe(Order order) { string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString; ; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.VoegOrderToe; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("KlantNaam", order.KlantNaam); command.Parameters.AddWithValue("OrderDatum", order.OrderDatum); command.Parameters.AddWithValue("Status", order.Status); try { connection.Open(); command.ExecuteNonQuery(); int orderID; command.CommandText = "SELECT @@IDENTITY"; if (int.TryParse(command.ExecuteScalar().ToString(), out orderID)) { order.ID = orderID; using (SqlCommand orderDetailCommand = connection.CreateCommand()) { orderDetailCommand.CommandType = CommandType.Text; foreach (OrderDetail orderDetail in order.OrderDetails) { orderDetailCommand.CommandText = OrderDaoQueries.VoegOrderDetailToe; orderDetailCommand.Parameters.Clear(); orderDetailCommand.Parameters.AddWithValue("OrderID", order.ID); orderDetailCommand.Parameters.AddWithValue("Aantal", orderDetail.Aantal); orderDetailCommand.Parameters.AddWithValue("Bedrag", orderDetail.Bedrag); orderDetailCommand.Parameters.AddWithValue("Eenheid", orderDetail.Eenheid); orderDetailCommand.Parameters.AddWithValue("Omschrijving", orderDetail.Omschrijving); orderDetailCommand.Parameters.AddWithValue("StukPrijs", orderDetail.StukPrijs); orderDetailCommand.ExecuteNonQuery(); } } } } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } } public void BestelOrder(Order order) { string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.BestelOrder; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("ID", order.ID); command.Parameters.AddWithValue("Status", order.Status); try { connection.Open(); command.ExecuteNonQuery(); } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } } public void MeldOrderBinnen(Order order) { string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString; ; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.MeldOrderBinnen; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("ID", order.ID); command.Parameters.AddWithValue("Status", order.Status); try { connection.Open(); command.ExecuteNonQuery(); } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } } public void LeverOrderUit(Order order) { string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString; ; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.LeverOrderUit; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("ID", order.ID); command.Parameters.AddWithValue("Status", order.Status); try { connection.Open(); command.ExecuteNonQuery(); } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } } public void WijzigOrder(Order order) { string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString; ; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.WijzigOrder; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("ID", order.ID); command.Parameters.AddWithValue("Status", order.Status); command.Parameters.AddWithValue("KlantNaam", order.KlantNaam); command.Parameters.AddWithValue("OrderDatum", order.OrderDatum); try { connection.Open(); command.ExecuteNonQuery(); using (SqlCommand orderDetailCommand = connection.CreateCommand()) { orderDetailCommand.CommandType = CommandType.Text; foreach (OrderDetail orderDetail in order.OrderDetails) { orderDetailCommand.CommandText = OrderDaoQueries.WijzigOrderDetail; orderDetailCommand.Parameters.Clear(); orderDetailCommand.Parameters.AddWithValue("ID", orderDetail.ID); orderDetailCommand.Parameters.AddWithValue("OrderID", order.ID); orderDetailCommand.Parameters.AddWithValue("Aantal", orderDetail.Aantal); orderDetailCommand.Parameters.AddWithValue("Bedrag", orderDetail.Bedrag); orderDetailCommand.Parameters.AddWithValue("Eenheid", orderDetail.Eenheid); orderDetailCommand.Parameters.AddWithValue("Omschrijving", orderDetail.Omschrijving); orderDetailCommand.Parameters.AddWithValue("StukPrijs", orderDetail.StukPrijs); orderDetailCommand.ExecuteNonQuery(); } } } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } } public void VerwijderOrder(Order order) { string connectionString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString; ; using (SqlConnection connection = new SqlConnection(connectionString)) { using (SqlCommand command = connection.CreateCommand()) { command.CommandText = OrderDaoQueries.VerwijderOrder; command.CommandType = CommandType.Text; command.Parameters.AddWithValue("ID", order.ID); try { connection.Open(); using (SqlCommand orderDetailCommand = connection.CreateCommand()) { orderDetailCommand.CommandType = CommandType.Text; foreach (OrderDetail orderDetail in order.OrderDetails) { orderDetailCommand.CommandText = OrderDaoQueries.VerwijderOrderDetail; orderDetailCommand.Parameters.Clear(); orderDetailCommand.Parameters.AddWithValue("ID", orderDetail.ID); orderDetailCommand.Parameters.AddWithValue("OrderID", order.ID); orderDetailCommand.ExecuteNonQuery(); } } command.ExecuteNonQuery(); } catch (SqlException ex) { // log error // implement a Exception Handling strategy throw new Exception("Er is een fout opgetreden tijdens de communicatie met de database, neem contact op met de applicatiebeheerder.", ex); } finally { if (connection.State == ConnectionState.Open) connection.Close(); } } } } #endregion } }[/source] We hebben nu de OrderDao geïmplementeerd, nu moeten we de DoaFactory nog implementeren. De implementatie van de DaoFactory zorgt ervoor dat de juiste instantie wordt aangemaakt voor de Dao. We voegen weer een nieuwe class toe aan de OrderSystem.DataLayer.SqlServer class library met de naam SqlDaoFactory. De inhoud ziet er zo uit: [source:C-sharp]using System; using System.Collections.Generic; using System.Text; namespace OrderSystem.DataLayer.SqlServer { public class SqlDaoFactory : DaoFactory { /// /// Gets an SqlServer specific order data access object. /// public override IOrderDao OrderDao { get { return new OrderDao(); } } } }
We hebben nu de concrete implementatie van de SqlServer af. Wat hier nog beter kan is: code generiek maken, bijvoorbeeld door een DbHelper class toe te voegen.
De volgende keer gaan we verder met het implementeren van de Business Layer.

