2

I am trying to attach an object that exists in the database to new DbContext, modify a single value (property: SubmissionGrpID, which is a foreign key) and then save the changes to the database. I am trying to do this without having to load the whole entity into the DbContext from the database.

I have already seen the question: How to update only one field using Entity Framework? but the answers did not help me.

The property: ID in the PnetProdFile table is the only column used in the primary key for that table. The code I am using is below:

using (SomeEntities db = new SomeEntities())
{
    foreach (var id in FileIds)
    {
        PnetProdFile file = new PnetProdFile();
        file.ID = id; // setting the primary key
        file.SubmissionGrpID = 5; // setting a foreign key

        db.PnetProdFiles.Attach(file);
        var entry = db.Entry(file);
        entry.Property(e => e.SubmissionGrpID).IsModified = true;
    }
    db.SaveChanges();
}

When I run the code, I get the following exception:

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

Then, after adding in the following line of code before I SaveChanges():

var errors = db.GetValidationErrors();

I get all the Not Null fields as required values for the PnetProdFile table in the Validation Errors. One way to prevent validation errors is to set

db.Configuration.ValidateOnSaveEnabled = false;

but then that prevents validation on the entire entity, even on properties that could have been updated.

So, to summarise, I am trying to update an object which already exists in the database without loading the related record from the database, and only get validation errors on properties that have been changed. How can this be done?

Community
  • 1
  • 1
Stu
  • 69
  • 7

2 Answers2

1

By default EF validates all Added and Modified entities. You can modify this behavior by overwriting the DbContext.ShouldValidateEntity method where you would return false for entities you don't want to be validated.

Pawel
  • 31,342
  • 4
  • 73
  • 104
0

Attached rather than loaded/read Objects default to UnChanged If you are using Rowversion/Timestamp optimistic locking then you must read the object first. But if you have a vanilla object....

 Context.Entry(poco).State = state; // tell ef what is going on.
 Context.SaveChanges();
//    Detached = 1,
//    Unchanged = 2,
//    Added = 4,
//    Deleted = 8,
//   Modified = 16,

There is also the option "AddOrdUpdate"

   Context.Set<TPoco>().AddOrUpdate(poco);
   Context.SaveChanges();

This option was originally intended for seed type scenarios. People seem to be using it more in everyday cases. I only use it for seeding. Do a quick search on pros and cons of AddOrdUpdate before you use it in everyday production scenarios.

More on working with detached entities here

phil soady
  • 11,043
  • 5
  • 50
  • 95
  • The concurrency modes for all the properties in my .edmx file are set to "none", not "fixed", so I would take it that my object is vanilla. I am using Entity Framework 6 and could not find the method 'Context.Set().AddOrUpdate()'. I did find a way of getting it to work by setting the 'db.Configuration.ValidateOnSaveEnabled = false;' before submitting changes. Not sure if that is the best way of doing it? – Stu Nov 21 '13 at 13:47
  • Im using EF6. AddOrUpdate is there: See -> namespace System.Data.Entity.Migrations public static class DbSetMigrationsExtensions Method public static void AddOrUpdate(this IDbSet set, params TEntity[] entities) – phil soady Nov 21 '13 at 22:52