Код Entity Framework Ошибка первого обновления с выгруженным обязательным свойством навигации - PullRequest
3 голосов
/ 15 декабря 2011

Я обнаружил, что, если я устанавливаю свойство навигации как требуется (используя атрибут Required) и использую прокси с отложенной загрузкой, когда я загружаю родительскую сущность и ничего не делаю, но пытаюсь сохранить в том же контексте, возникает EntityValidationError что похоже на «поле ххх обязательно».

С помощью hibernate в Java и NHibernate в .NET можно просто получить объект без его свойств навигации (все загружены с отложенной загрузкой), обновить его и снова сохранить. Фреймворк понимает, что ничего не изменилось с навигационными ссылками и не выдает никаких ошибок.

Пример ниже

[Table("Address")]
public class Address
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AddressId { get; set; }

    [Required, StringLength(512)]
    public virtual string AddressLine1 { get; set; }
}

[Table("User")]
public class User
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }

    [Required]
    public string Name {get; set;}

    [Required]
    public virtual Address Address {get; set;}


}


void LoadAndSaveUser() {
    var user = Context.Users.First();
    user.Name = "foo";

    // if i comment out this line 
    // ( probably EF fetches the lazy loaded entiy ) 
    // the code works. it is strange though because i don't access any property/method of the Address

    // var dummy = user.Address

    Context.SaveChanges();
}

Когда я пытаюсь сделать это без атрибута «Required» в свойстве Address, ошибки не возникает. С атрибутом Required я получаю «Адресное поле обязательно!». Поскольку у каждого пользователя должен быть адрес, я хочу, чтобы атрибут создавал непротиворечивую модель.

На некоторых форумах я обнаружил посты, предлагающие включить свойство навигации при загрузке родительской сущности (другими словами, нетерпеливую загрузку), но это нереальный подход, если у нас слишком много навигационных свойств.

Я делаю что-то не так или есть другой способ реализовать такую ​​функциональность?

1 Ответ

1 голос
/ 15 декабря 2011

Определите public int AddressId в вашем классе User. Он загружается всякий раз, когда загружается пользователь. Я думаю, что это решит проблему.

Обновление : Ну, я воспроизвел вашу проблему. У вас есть несколько вариантов, чтобы предотвратить это. Но одно точно. Вы должны удалить атрибут [Обязательный] из вашего свойства Address. Это источник вашей проблемы (который является рациональным, поскольку вы говорите EF: «Я хочу, чтобы присутствовал объект Address object (не внешний ключ, а свойство навигации). Если он нулевой, выведите исключение» ).
Кроме того, определите AddressId свойство типа int в вашем User классе.

Обратите внимание, что вы также можете определить public virtual ICollection<User> Users { get; set; } в вашей Address сущности.

Вы можете сообщить EF об обязательном атрибуте, указав [Required] на AddressId или используя свободный API:
в вашем классе отображения пользователей:
this.HasRequired (t => t.Address) .Со многими() .HasForeignKey (d => d.AddressId);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...