1

I am trying to update only some of the fields in a table. I created a view model with the fields that need to be updated. There are other fields in the table that don't need to be touched so they have been left oiut of the view model.

When I execute SaveChanges(), I get an error about a field not included in the view model, cannot be NULL. Since this is a partial update, I thought the fields not included in the view model should just be left alone on the update.

The Exception:

Cannot insert the value NULL into column 'NewClubName', table 'dbo.NewClub'; 
column does not allow nulls. UPDATE fails

Here is what I have:

//View Model
    public class FormANewClubTeamViewModel
    {
        /******************************************************
            Properties for Domain Model "NewClub"
        *******************************************************/
        public int NewClub_Id { get; set; }

        //District and Division
        public string District { get; set; }
        public string Division { get; set; }

        //Lt Governor
        public string LtGovMasterCustomerId { get; set; }
        public string LtGovContact { get; set; }
        public string LtGovEmail { get; set; }
        public string LtGovPhone { get; set; }

        // Club Counselor
        public string ClubCounselorMasterCustomerId { get; set; }

        [Display(Name = "Club counselor")]
        [Required(ErrorMessage = "Club counselor name")]
        public string ClubCounselorContact { get; set; }

        [Display(Name = "Club counselor email")]
        [Required(ErrorMessage = "Club counselor email")]
        public string ClubCounselorEmail { get; set; }

        [Display(Name = "Club counselor phone")]
        [Required(ErrorMessage = "Club counselor phone")]
        public string ClubCounselorPhone { get; set; }

        /******************************************************
           Properties for Domain Model "NewClubSponsor"
       *******************************************************/
        public List<NewClubSponsor> Sponsors { get; set; }
    }


 //Controller doing the update
        if (ModelState.IsValid)
        {

            if (model.NewClub_Id > 0)
            {
                httpStatus = HttpStatusCode.OK;

                NewClub newClub = new NewClub
                    {
                        Id = model.NewClub_Id,
                        ClubCounselorMasterCustomerId = model.ClubCounselorMasterCustomerId,
                        ClubCounselorContact = model.ClubCounselorContact,
                        ClubCounselorEmail = model.ClubCounselorEmail,
                        ClubCounselorPhone = model.ClubCounselorPhone,
                        DateUpdated = DateTime.Now


                    };

                db.NewClubs.Add(newClub);
                db.Entry(newClub).State = EntityState.Modified;

                try
                {
                    var dbResult = db.SaveChanges() > 0;

                }
                catch (SqlException ex)
                { 
                   [...]
                }
Slinky
  • 5,662
  • 14
  • 76
  • 130
  • can you explain more and give the exception details? – ilay zeidman Jan 07 '14 at 17:47
  • sure. i updated the question. the gist of it is there is a column in the table that cannot be null. this column does not need to be updated at this point so i don't know why EF cares about it ON UPDATE. – Slinky Jan 07 '14 at 17:53
  • When you create new entities the fields that you don't need has default values(null) and that why it throw exception. – ilay zeidman Jan 07 '14 at 17:56

3 Answers3

5

The problem here is that EF does not have any mean to know whether you are updating this particular property to be NULL, or do not want to update it at all.

As far as I know there is no way to make such partial update in EF (unless you are willing to introduce some pure SQL code into your data access layer), as for now. Meaning that for the update to take place you need to load the entity, update its fields, and save the changes:

if (model.NewClub_Id > 0)
{
    httpStatus = HttpStatusCode.OK;

    NewClub newClub = db.NewClubs.Single(nc => nc.Id == model.NewClub_Id);

    newClub.ClubCounselorMasterCustomerId = model.ClubCounselorMasterCustomerId;
    newClub.ClubCounselorContact = model.ClubCounselorContact;
    newClub.ClubCounselorEmail = model.ClubCounselorEmail;
    newClub.ClubCounselorPhone = model.ClubCounselorPhone;
    newClub.DateUpdated = DateTime.Now;

    try
    {
        var dbResult = db.SaveChanges() > 0;
    }
    catch (SqlException ex)
    { 
       [...]
    }
}
Andrei
  • 55,890
  • 9
  • 87
  • 108
3

According to this answer: https://stackoverflow.com/a/9821029

Partial updates in EF are possible without fetching the entity from the database first.

Community
  • 1
  • 1
Yaron
  • 1,867
  • 20
  • 16
1

Partial updates are possible in EF 4.1+ (Copied the original idea from this answer)

You can use following method;

public int Update(T entity, params Expression<Func<T, object>>[] properties)
{
  myDataContext.Entry(entity).State = EntityState.Unchanged;

  foreach (var property in properties)
  {
    var propertyName = ExpressionHelper.GetExpressionText(property);
    myDataContext.Entry(entity).Property(propertyName).IsModified = true;
  }

  return myDataContext.SaveChangesWithoutValidation();
}

And use as;

Update(YourModel, m=> m.Name);

or

Update(YourModel, m=> m.Name, m.Address, m.OtherProperty);
Community
  • 1
  • 1
Dilhan Jayathilake
  • 1,860
  • 2
  • 17
  • 15