Exercício ADO.NET – Shop Actualizar dados do Cliente Actualizar dados de um cliente usando uma DetailsView para actualizar os dados.O cliente é seleccionado numa GridView com todos os clientes. 1 Implementar método GetAll(string user,string pass) da classe Customer que usa método genérico GetAllFromTable da classe UtilDB 2 – Implementar método bindClientes() private void bindclientes() { ShopClassLibrary.ICustomer customer = ShopClassLibrary.Factory.CreateCustomerService(); DataSet ds = customer.GetAll(); gvClientes.DataSource = ds; gvClientes.DataBind(); } 3 – Implementar o método: private void bindDetalhesClientes(long id) { // usa GetById da classe customer 4 – Implementar o evento: protected void gvClientes_SelectedIndexChanged(object sender, EventArgs e) { string idstr = (gvClientes.SelectedDataKey.Value.ToString()); // usar o método anterior para carregar a DetailsView com informação do cliente a) configurar a propriedade DataKey da GridView com o valor CustomerID b) a propriedade SelectedDataKey vai permitir aceder ao valor do CustomerID da linha seleccionada na grelha 5 – Implementar o seguinte evento para alterar estado da DetailView protected void dvClientes_ModeChanging(object sender, DetailsViewModeEventArgs e) { if (dvClientes.CurrentMode == DetailsViewMode.ReadOnly) { dvClientes.ChangeMode(DetailsViewMode.Edit); string idstr = gvClientes.SelectedDataKey.Value.ToString(); long id = long.Parse(idstr); bindDetalhesClientes(id); } else if (dvClientes.CurrentMode== DetailsViewMode.Edit) { dvClientes.ChangeMode(DetailsViewMode.ReadOnly); string idstr = gvClientes.SelectedDataKey.Value.ToString(); long id = long.Parse(idstr); bindDetalhesClientes(id); } } a) O método ChangeMode permite mudar o estado da DetailsView para ReadOnly, Edit ou Insert 6 – Implementar o seguinte evento protected void dvClientes_ItemUpdating(object sender, DetailsViewUpdateEventArgs e) { ShopClassLibrary.ICustomer customer = ShopClassLibrary.Factory.CreateCustomerService(); long id = long.Parse(dvClientes.Rows[0].Cells[1].Text); string name = ((TextBox)dvClientes.Rows[1].Cells[1].Controls[0]).Text; … // aceder aos outros valores e fazer Update na base de dados // Para isso implementar método Update na classe Customer a) A DetailsView tem: Uma colecção de Rows Cada Row tem uma colecção de Cells Cada Cells tem uma colecção de Controls Cada Control tem as suas propriedades 7 – Faça as alterações necessárias para fazer validações nas TextBox da DetailsView. Por exemplo validar o número de telefone. Edit Fields -> Convert this field into a TemplateField Edit Template -> EditItemTemplate Acrescentar Validators Inserir Venda Acrescentar linhas de encomenda Pretende-se ir acrescentando produtos à venda guardando os seus valores num DataSet, com os mesmos campos (Schema) da tabela SalesDetails. O DataSet é guardado numa variável de sessão. Apenas quando se fecha a factura é gravada a informação na base de dados. 1 - Para carregar as DropDownList usar métodos: DataSet dsprodutos = produtos.getAll(user,pass) DataSet dsclientes = clientes.getAll(user,pass) Definir propriedades nas DropDownList ddlProdutos.DataValueField = "ProductID"; ddlProdutos.DataTextField = "Description"; 2 - Criar DataSet vazio a partir da tabela SalesDetails, para ir inserindo os produtos encomendados: ShopClassLibrary.ISale sale = new ShopClassLibrary.Sale(); DataSet dsdetalhes = sale.CreateDetails("admin", "admin"); O método CreateDetails devolve um DataSet vazio, com o mesmo esquema da tabela, a partir da tabela SalesDetails. ds = UtilDB.GetByID(conn, null, "SaleDetails", "SaleID", -1); Acrescentar uma coluna à tabela do DataSet para o nome do produto dsdetalhes.Tables[0].Columns.Add("Produto"); 3 – Guardar o DataSet numa variável de sessão Session["detalhes"] = dsdetalhes; 4- No evento Click do Button Acrescentar implementar: Aceder aos valores do formulario: string produtoID = ddlProdutos.SelectedValue; Aceder ao DataSet DataSet dsdetalhes = (DataSet)Session["detalhes"]; Criar uma nova linha ( DataRow ) na tabela do DataSet DataRow dr = dsdetalhes.Tables[0].NewRow(); Prencher campos da linha dr["ProductID"] = produtoID; ... Acrescentar a nova linha à tabela dsdetalhes.Tables["SaleDetails"].Rows.Add(dr); Actualizar GridView e guardar o DataSet 5 - Gravar a Venda (consultar Referência rápida ADO.net) // iniciar transacção tx = conn.BeginTransaction(); // validar o utilizador // validar cliente DataSet dsCust = UtilDB.GetByID(conn, tx, "Customers", "CustomerID", CustomerID); if (dsCust.Tables["Customers"].Rows.Count == 0) return ShopStatusEnum.INVALID_CUSTOMER_ID; // verificar se há produtos no dataset de entrada ... // Criar DataSet com os produtos para consultar o preço unitário de cada produto // (pode não ser a melhor solução se os produtos forem muitos) Product products = new Product(); DataSet dsprodutos = products.getAll(user, pass); // Definir chave primária – ProductID - da tabela DataColumn[] dc = new DataColumn[1]; dc[0]=dsprodutos.Tables[0].Columns[0]; dsprodutos.Tables[0].PrimaryKey = dc; DataTable t = dsprodutos.Tables[0]; // validar produtos no DataSet e calcular custo total de cada produto // iterando sobre o DataSet da venda – RsDetails foreach (DataRow regDetails in RsDetails.Tables["SaleDetails"].Rows) { if (regDetails.IsNull("ProductID")) return ShopStatusEnum.INVALID_ARGUMENT; // validar quantidade ... // ler ID do produto int pid=(int) regDetails["ProductID"]; // usar método find, da colecção de Rows, para procurar produto com esse ID DataRow dr = t.Rows.Find(pid); // calcular e actualizar na tabela o preço total do produto float uprice = float.Parse(dr["UnitPrice"].ToString()); float total=uprice* ((int) regDetails["Quantity"]); regDetails["TotalCost"] = total; // criar comando para inserção da venda ... // registar transsacção no comando cmd.Transaction = tx; // definir parâmetros do comando ( ver como definir parâmetro Date) ... // executar comando para inserir registo ... // obter id autogerado OleDbCommand cmdID = new OleDbCommand("SELECT @@IDENTITY", conn); int id = (int)cmd.ExecuteScalar(); // inserir chave estrangeira nas linhas de detalhe iterando sobre o DataSet ... regDetails["SaleID"] = id; // inserir linhas de detalhe usando o CommandBuilder OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM SaleDetails",conn); da.SelectCommand.Transaction = tx; OleDbCommandBuilder cb = new OleDbCommandBuilder(da); da.Update(RsDetails, "SaleDetails"); // fechar transacção tx.Commit(); } // tratar excepções if (tx != null) tx.Rollback();