none
Maestro-Detalle con databindingsource , problema al añadir RRS feed

  • Pregunta

  • Hola

     

    llevo un tiempo dándole vueltas a como solucionar un problema de una forma limpia y eficiente.

    Voy a intentar explicar-me con la mayor claridad posible , para ello he creado un ejemplo de mi problema usando la base de datos Northwind, base de datos ampliamente conocida.

    El siguiente código es un formulario CRUD de un maestro-detalle.

    La modificacion del maestro funciona bien , la del detalle también.

    El problema me lo encuentro cuando creo un nuevo maestro y empiezo a añadir detalles en el datagridview, como el maestro no esta guardado aún en la base de datos sale un error en el datagridview quej 

    Me interesa que todo se guarda cuando se pulse el botón "Guardar" y que si no , no se guarde ( se pueda cancelar).

        public partial class Form1 : Form
        {
          
      private String conStr = @"Server=PC\SQLEXPRESS;Database=Northwind;Trusted_Connection=True;";
            private DataSet dsData;
            
    
            public Form1()
            {
                InitializeComponent();
            }
    
            
            private void GetData() {
    
                dsData = new DataSet();
                using (SqlConnection con = new SqlConnection(conStr)) {
                    con.Open();
    
                    SqlDataAdapter daMaster = new SqlDataAdapter("SELECT * FROM Orders",con);
                    daMaster.Fill(dsData,"Orders");
    
                    SqlDataAdapter daDetail = new SqlDataAdapter( "SELECT * FROM \"Order Details\"",con);
                    daDetail.Fill(dsData, "OrderDetails");
    
                    dsData.Tables["Orders"].PrimaryKey = new DataColumn[] { dsData.Tables["Orders"].Columns["OrderID"] };
                    
                    dsData.Tables["OrderDetails"].PrimaryKey 
                        = new DataColumn[] { dsData.Tables["OrderDetails"].Columns["OrderId"],
                                             dsData.Tables["OrderDetails"].Columns["ProductId"]};
                    
                    
                    dsData.Relations.Add(
                        new DataRelation("MasterDetail",
                            dsData.Tables["Orders"].Columns["OrderId"],
                            dsData.Tables["OrderDetails"].Columns["OrderId"]));
                    
                    bsMaster.DataSource = dsData;
                    bsMaster.DataMember = "Orders";
    
                    bsDetail.DataSource = bsMaster;
                    bsDetail.DataMember = "MasterDetail";
                }
            
            }
            private void Form1_Load(object sender, EventArgs e)
            {
                GetData();
                BindControls();
                dataGridView1.AutoGenerateColumns = true;
            }
    
    
            private void BindControls() {
    
                txtOrderId.DataBindings.Add("Text", bsMaster, "OrderID");
                txtCustomerId.DataBindings.Add("Text", bsMaster, "CustomerId");
                txtEmployeId.DataBindings.Add("Text", bsMaster, "EmployeeID");
                dtOrderDate.Enabled = false;
                dtOrderDate.Visible = false;
                dtRequiredDate.Enabled = false;
                dtRequiredDate.Visible = false;
                dtShippedDate.Enabled = false;
                dtShippedDate.Visible = false;
                // dtOrderDate.DataBindings.Add("Value", bsMaster, "OrderDate");
               // dtRequiredDate.DataBindings.Add("Value", bsMaster, "RequiredDate");
               // dtShippedDate.DataBindings.Add("Value", bsMaster, "ShippedDate");
                txtShipVia.DataBindings.Add("Text", bsMaster, "ShipVia");
                txtShipName.DataBindings.Add("Text", bsMaster, "ShipName");
                txtShipAddress.DataBindings.Add("Text", bsMaster, "ShipAddress");
            }
    
            private void guardarToolStripButton_Click(object sender, EventArgs e)
            {
                bsMaster.EndEdit();
                bsDetail.EndEdit();
                SaveChanges();
            }
    
            private void SaveChanges() {
    
                String master = "Orders";
                String detail = "OrderDetails";
    
                using (SqlConnection con = new SqlConnection(conStr)) {
                    
                    SqlDataAdapter daMaster = new SqlDataAdapter("SELECT * From Orders",con);
                    SqlCommandBuilder cmdbld = new SqlCommandBuilder(daMaster);
    
                    SqlDataAdapter daDetail = new SqlDataAdapter("SELECT * FROM \"Order Details\"", con);
                    cmdbld = new SqlCommandBuilder(daDetail);
    
                    // Borrar hijos
                    daDetail.Update( dsData.Tables[detail].Select(null, null, DataViewRowState.Deleted));
    
                    // Borrar padres
                    daMaster.Update(dsData.Tables[master].Select(null, null, DataViewRowState.Deleted));
    
                    // Actualizar padres
                    daMaster.Update(dsData.Tables[master].Select(null, null, DataViewRowState.ModifiedCurrent));
    
                    // Insertar padres
                    daMaster.Update(dsData.Tables[master].Select(null, null, DataViewRowState.Added));
    
                    // Actualitzar hijos
                    daDetail.Update(dsData.Tables[detail].Select(null, null, DataViewRowState.ModifiedCurrent));
    
                    // Insertar Hijos
                    daDetail.Update(dsData.Tables[detail].Select(null, null, DataViewRowState.Added));
                }
            }
    
        }
    


    Notar que el problema no esta al guardar , sino al insertar datos en la grilla , osea los datos están en el bindingsource.

     

    Muchas gracias!

    domingo, 4 de septiembre de 2011 21:02

Todas las respuestas