0

I'm learning EF Code First and am having trouble when updating existing records. I've boiled it down to this simple example:

This works:

using(var db = new DataContext()){
   var p = db.People.Find(1);
   p.Name="New Name";
   Console.WriteLine(p.Gender.Name); //<--Unnecessary property access
   db.SaveChanges(); //Success
}

...but this fails (when the WriteLine is removed):

using(var db = new DataContext()){
   var p = db.People.Find(1);
   p.Name="New Name";
   db.SaveChanges(); //DbValidationError "Gender field is required."
}

Why do I have to access/load the Gender propery if I'm not using it and the data is already correctly stored in the database? I just want to change the Name on an existing record. In this example, Gender is a one-to-many association stored as Gender_Id in the People table. The classes are defined like this:

public class Person
{
    [Key]
    public int PersonId { get; set; }

    [Required, MaxLength(50)]
    public string Name { get; set; }

    [Required, Column("Gender")]
    virtual public GenderCode Gender { get; set; }
}

public class GenderCode
{
    [Key]
    public int Id { get; set; }

    [Required, MaxLength(10)]
    public string Name { get; set; }
}

public class DataContext:DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<GenderCode> GenderCodes { get; set; }
}

Of course, the fully defined classes are to have many more fields. I'd rather not have to access every dependant property every time I want to modify an unrelated value.

Is there a way to load an object, change a field, and save it without loading all related objects first?

smalltowndev
  • 715
  • 8
  • 13

2 Answers2

1

Yes, this is necessary because of some horrible design mistakes in EF.

Check out my similar question, EF: Validation failing on update when using lazy-loaded, required properties

One trick is declaring FK properties along with the OO relations:

[ForeignKey("GenderId"), Column("Gender")]
virtual public GenderCode Gender { get; set; }
[Required]
public int GenderId { get; set; }
Community
  • 1
  • 1
Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
0

It is because you are using data annotations and Required attribute has also meaning for validation. Once you set navigation property as Required by data annotation it must be filled / loaded when you are going to persist entity to the database.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670