Проблема с отложенной загрузкой и требуемым атрибутом: требуется поле XXX

#asp.net-mvc #asp.net-mvc-3 #data-annotations #ef-code-first #entity-framework-4.1

#asp.net-mvc #asp.net-mvc-3 #данные-аннотации #ef-code-first #entity-framework-4.1

Вопрос:

У меня есть Comment класс, обладающий, среди прочего, Author свойством:

 public class Comment : IEquatable<Comment>
{
    public int ID { get; set; }

    [Required]
    public virtual User Author { get; set; }

    // More properties here
}
  

Я хочу, чтобы пользователи могли ставить «лайк» комментарию, как здесь, в StackOverflow. С этой целью у меня есть следующее действие в моем CommentController :

 public virtual ActionResult Like(int id)
{
    var comment = _session.Single<Comment>(c => c.ID == id);
    comment.Likes  ;

    _session.CommitChanges();

    return Json(new { comment.Likes });
}
  

Всякий раз, когда я вызываю это действие, я получаю следующую ошибку проверки:

Требуется поле Author.

Comment Объект поступает из базы данных, поэтому у него есть автор. «Забавно» то, что всякий раз, когда я использую отладчик Visual Studio, чтобы проверить, действительно ли Author отсутствует, ошибка проверки не выдается.

Прав ли я, предполагая здесь, что проблема заключается в том, что отложенная загрузка Author свойства никогда не выполняется? Если да, то как я могу, только для этой ситуации, принудительно заполнить все свойства навигации? (В противном случае я хочу продолжать работать с отложенной загрузкой)

Какой самый аккуратный способ решить это? Я вообще на правильном пути? И почему не происходит отложенной загрузки, в то время как EF явно требует сохранения объекта?

Мы будем признательны за любую помощь.

Комментарии:

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

2. @Hightechrider — Сначала я использую код, и одна из вещей, RequiredAttribute которые он делает, — это пометить отношение FK как ON DELETE CASCADE , чего я и хотел здесь. И MSDN говорит об этом RequiredAttribute : «Указывает, что значение поля данных является обязательным». . Это не только для строк, AFAIK.

Ответ №1:

Вы могли бы использовать Include для быстрого извлечения отношения в контексте данных.

 context.Comments.Include("Author").Single<Comment>(c => c.ID == id);
  

Комментарии:

1. Спасибо @Darin — Есть ли какой-либо другой способ? Это вынудило бы меня «выйти» из моей реализации Unit of Work и использовать context непосредственно в моем действии, чего я бы предпочел не делать. Теперь все это так красиво абстрагировано и слабо связано … 🙂

2. Я полагаю, я всегда мог бы добавить EagerSingle<T>() метод в свой ISession интерфейс.

3. @Sergi Papaseit, вы могли бы использовать уровень сервиса, инкапсулирующий эту логику и предоставляющий Like(int commentId) метод. В обязанности контроллера не входит выполнение таких действий, как извлечение комментариев, Likes обновление. Все, что для этого нужно, это вызвать соответствующий метод service.

4. @Darin — Не будет ли это излишеством в данной ситуации? Для этого действия не так много кода, и нет ничего, чего «действительно не должно там быть», не так ли?

5. @Sergi Papaseit, контроллеры не должны быть жирными. Посадите их на диету .

Ответ №2:

У меня была похожая проблема. Приведенное ниже должно работать (с включенной ленивой загрузкой).

 public virtual ActionResult Like(int id)
{

   var comment = _session.Single<Comment>(c => c.ID == id);
   comment.Likes  ;

   if(TryUpdateModel(comment))
   {

       _session.CommitChanges();

   }
   return Json(new { comment.Likes });
}
  

Комментарии:

1. Я пробовал, и это действительно работает. Хотя это кажется хакерским. Это скорее обходной путь, чем решение, не так ли?

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