views:

523

answers:

2

Given a DataGridView that has a BindingSource set like this:

On a winform, we add a BindingSource object using the designer, called myBindingScource. Then on the Form.Designer.cs we add this to the InitializeComponents()

myBindingSource.DataSource = typeof(MyLinq.Person); //Mylinq is the autogenerated Linq Model/Diagram

Later, in the form itself we do:

myDataView.DataSource = myBindingSource;

and then we have a method that populates the Grid…

using ( myDataContext mdc = new MyDataContext() )
{
    myDataView.DataSource = from per in mdc.person
                            select per;
}

As an aside note, I've set up the columns in Design Time, and everything shows ok. Since the LINQ 2 SQL is not returning an Anonymous, the "myDataView" is editable, and here comes the question…

Question is: how do I persist those changes?

There are dozens of events in the datagrid, and I'm not sure which one is more appropriate. Even if I try one of the events, I still don't know what is the code I need to execute to send those changes back to the DB in order to persist the changes.

I remember back in the ADO.NET DataSet days, you would do dataadapter.Update(dataset);

Also imagine that both the retrieve and the persist() are on a Business Layer and the method signature looks like this:

public void LoadMyDataGrid(DataGridView grid);

that method takes the form's grid and populates it using the LINQ2SQL query shown above.

Now I'd like to create a method like this:

public void SaveMyDataGrid(DataGridView grid); // or similar

The idea is that this method is not on the same class (form), many examples tend to assume that everything is together.

+2  A: 

RowValidated event would be a good place to check to see if it's time to persist changes to the database.

    this.dataGridView1.RowValidated += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_RowValidated);

    private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
    {
        MyLinq.Person person = dataGridView1.Rows[e.RowIndex].DataBoundItem as MyLinq.Person;

        if (person != null)
        {
            // save this person back to data access layer
        }
    }

After your edit:

I wouldn't pass back a datagrid instance to your service layer. I'd pass back IEnumerable<MyLinq.Person> or IList<MyLinq.Person> then iterate over the collection in your service layer, and depending on the logic performed; persist the changes to the data access layer (your database)

Michael G
I was interested in the "//save this person" part of the code.I have a person object that came from the DB and was placed in a row. The row was edited. Now I want LINQ to put those changes back. In NHIBERNATE and others, there were ".save()" or ".persist()" methods on each Class/Object. But I don't know how to tell LINQ (by reading cloggings' sample below), to update the person object.
Martín Marconcini
I have found the solution (Attach) here: http://geekswithblogs.net/michelotti/archive/2007/12/17/117791.aspx
Martín Marconcini
+1  A: 

The 'save' method on the DataContext object is SubmitChanges().

using (MyContext c = new MyContext())
{
     var q = (from p in c.People
             where p.Id == 1
             select p).First();
     q.FirstName = "Mark";
     c.SubmitChanges();
}

As Michael G mentioned, you'll need to gather the changes, and pass them back to the bll object.

cloggins
But if I have a People object that comes from a Row in the Datagrid, how can I tell the DataContext to update that "Person"? I remember in other OR Mappers each object had a .persist() or .save() method. The object retrieved from MichaelG's code is a "Person" object. I need to tell LINQ, go ahead and update this Person.
Martín Marconcini
See the above comment, the solution is that I need to "attach" the disconnected object back, and I needed I timestamp.
Martín Marconcini