views:

609

answers:

4

I have a simple row that has 4 Columns { [Primary Key Int]RowID, [text]Title, [text]Text, [datetime]Date }

I would like to allow the user to edit this row on a simple page that has a form with the fields "Title" and "Text".

There is a hidden field to store the RowID.

When the user posts this form to my controller action, I want it to update the row's Title and Text, and KEEP the Date the same. I don't want to have to explicitly include a hidden field for the Date in the form page.

Here is my action

[AcceptVerbs(HttpVerb.Post)]
public ActionResult EditRow(Row myRow)
{
    RowRepository.SaveRow(myRow)   
    return View("Success");
}

RowRepository

public void SaveRow(Row myRow)
{
    db.MyRows.Attach(myRow);
    db.Refresh(RefreshMode.KeepCurrentValues, myRow);
    db.SubmitChanges();
}

This dosen't keep the "Date" value already in the row and tries to insert a value that throws an timespan exception.

How can I just tell it to keep the old values? I tried doing RfreshMode.KeepChanges and nothing.

+1  A: 

I'm not in a position to test this at the moment but try making the datetime column nullable and then ensure that the datetime passed into SaveRow has a null value.

Lazarus
Hmm... you're right, it seems that a value of 1/1/0001 12:00:00 AM gets passed into Row.Date if its not given a value.If I make "Date" column nullable in Linq to SQL as nullable, then everytime I need to use it I would need to reffer to it as myRow.Date.Value correct?
Baddie
Yes, but a nullreferenceexceptions is possible. So check first before referencing that by if(myRow.Data.HasValue)...
mxmissile
+1  A: 

Try

[AcceptVerbs(HttpVerb.Post)]
public ActionResult EditRow([Bind(Exclude="Date")] Row myRow) {
  RowRepository.SaveRow(myRow)   
  return View("Success");
}

Update

Try this approach, where there is no 'Date' field on your page

[AcceptVerbs(HttpVerb.Post)]
public ActionResult EditRow(int RowID) {
  Row myRow = RowRepository.GetRow(RowID);
  UpdateModel(myRow);
  RowRepository.Save();
  return View("Success");
}

In your repository

public void Save() {
  db.SubmitChanges();
}

This will only save the changes made to 'myRow'

David G
Its still passing a null value
Baddie
Looking at your code, it would just pull the row from the datacontext, then submit changes and not actually do any changes. I know I can manually pull the row from the datacontext, then get the posted "Text" and "Title" fields, change the row's values for that, then call a submitchanges, but I want model binding to do the work.
Baddie
UpdateModel(myRow) is automatically doing the model binding for you. It will match the fields on the page to the Row object's properties. If your Row is a Linq to SQL object called via DataContext.Rows.Select() (or equivalent) then DataContext.SubmitChanges() will save any changes made to that Row object.
David G
Take a look at the MVC .Net Nerd Dinner free eBook http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx if you haven't already.
David G
A: 

Ok, I set it to nullable and it keeps overwriting the database as a null value. I guess its impossible to do this since technically null is a valid value for the column and if I pass an object to the function, the empty values must contain something or be null.

So I would have to explicitly state to take the database value for that column

Thanks

Baddie
No, it's quite possible, you just need to try a different approach. Linq to Sql will save only updated values. See try my updated answer.
David G
Check my comment on your answer.
Baddie
A: 

You will have add a method in the partial class / override the code it build.

The class Table does implement "INotifyPropertyChanging|ed" which is used to track which column has been changed.

You can hack it and reset the value "this.PropertyChanged".

But what I do at work is a stupid READ-APPLY-WRITE approach (and I am using WebForm).

public void SaveRow(Row myRow)
{
  var obj=db.MyRows.Where(c=>c.id==myRow.id).First();
  obj.a=myRow.a;
  obj.b=myRow.b;
  db.SubmitChanges();
}

You can do a bit simpler.

public void SaveRow(Row myRow)
{
    db.MyRows.Attach(new Row(){
      Id=myRow.Id,
      Title=myRow.Title,
      Text=myRow.Text,
    });
    db.SubmitChanges();
}

PS. I am new to Linq to sql. Please let me know if there is a smarter way to do.

Dennis Cheung