There are two approaches to work with the DataContext object. The first approach is to work with a single DataContext object which is responsible for all the quires and the manipulations in our system. In the second approach we work with several DataContext object. Each request refer to a single atomic operation and will work independency to others operation (The DataContext isn't aware to the previous operations at the current entity). The ASP.Net is a good example for the second approach because each request is being handled independently from the previous operation.
For example, if we'll create a user page with view and edit mode. In the first time that the page loads we present the user's details and after the client click on change name button we'll entire the edit mode and change the customer name.
public partial class User : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindUserDetailsView ();
}
}
private void BindUserDetailsView()
{
DataClasses2DataContext db1 = new DataClasses2DataContext();
IQueryable<Customer> customer = db1.Customers.Where(x =>x.Code==1);
UserView.DataSource=customer;
UserView.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
DataClasses2DataContext db2 = new DataClasses2DataContext();
// Init a new customer object and set the old object primary key
Customer customer = new Customer(){Code=1};
db2.Customers.Attach(customer);
customer.FirstName = "Yuval";
db2.SubmitChanges();
BindDetailsView();
}
}
In the first time the page will look like this:
And after we will click on the "Change name" button we create a new Customer instance and initialize it with the entity primary code. Then we need to attach it to our Customer collection and perform some changes and save them (By calling to the SubmitChanges method).
In this scenario we have tow separated data context object. In the first one we used to retrieve the customer details and in the second we used for the update the customer details.
If you want it to work you should do this steps:
- Create a new Customer entity object.
- Set the customer primary key (The primary key that has been defined in the database).
- "Attach" the customer object. It's telling the DataContext engine to look for this entity and trace all changes in it.
- Make some changes in the customer object.
- Call the SubmitChanges method. Behind the scene it performs an update operation on the database and puts the customer primary key in the "where statement". In this scenario we'll get something like this:
UPDATE Customers
SET FirstName = @p1
WHERE (Code = @p0)
Notice:
You must check the UpdateCheck parameter of the "Column" attribute for the "FirstName" and "LastName" columns. If the value of this parameter isn't equal to "System.Data.Linq.UpdateCheck.Never" you will get this error:
"Row not found or changed (System.Data.Linq.ChangeConflictException: Row not found or changed)".
b.t.w I really don't know why, but the auto generation code tools (SqlMetal and "Linq to sql file") don't generate the UpdateCheck parameter in the Column attribute. And therfore, we must add this parameter with the UpdateCheck.Never value, to each column that isn't an integration part from our table primary key. If you have any idea why the automatic tools aren't generating this piece of code, I'll be happy to learn.
Read more:
Introducing to DLINQ
· Introducing to DLINQ - Entities declaration - part 1
· Introducing to DLINQ – How to write the queries - part 2
· Introducing to DLINQ – How to write data manipulation in DLINQ (Update, insert and delete) - part 3
Advanced topics in DLINQ:
· DLINQ – Advanced topics – Transaction support – part 4
· DLINQ – Advanced topics – How it works in ASP.NET application – part 5
· DLINQ – Advanced topics – Debug mode – part 6