Нужно ли обращаться ко всем связанным объектам (lazyloaded), прежде чем можно будет сохранить существующий объект? - PullRequest
0 голосов
/ 01 ноября 2011

Я изучаю EF Code First и у меня возникают проблемы при обновлении существующих записей. Я свел это к следующему простому примеру:

Это работает:

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
}

... но это не удается (при удалении WriteLine):

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

Почему я должен обращаться к / загружать пол правильно, если я им не пользуюсь и данные уже правильно хранятся в базе данных? Я просто хочу изменить имя в существующей записи. В этом примере Gender - это связь «один ко многим», хранящаяся как Gender_Id в таблице People. Классы определены так:

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; }
}

Конечно, у полностью определенных классов должно быть гораздо больше полей. Я бы предпочел не иметь доступа к каждому зависимому свойству каждый раз, когда я хочу изменить несвязанное значение.

Есть ли способ загрузить объект, изменить поле и сохранить его, не загружая сначала все связанные объекты?

Ответы [ 2 ]

1 голос
/ 01 ноября 2011

Да, это необходимо из-за некоторых ужасных ошибок проектирования в EF.

Проверьте мой аналогичный вопрос, EF: Ошибка проверки при обновлении при использовании лениво загруженных, обязательных свойств

Один трюк объявляет свойства FK вместе с отношениями OO:

[ForeignKey("GenderId"), Column("Gender")]
virtual public GenderCode Gender { get; set; }
[Required]
public int GenderId { get; set; }
0 голосов
/ 01 ноября 2011

Это потому, что вы используете аннотации данных, а атрибут Required также имеет значение для проверки.После того как вы задали свойство навигации как Required с помощью аннотации данных, оно должно быть заполнено / загружено, когда вы собираетесь сохранить сущность в базе данных.

...