Почему Entity Framework иногда не включает свойства навигации? - PullRequest
0 голосов
/ 05 сентября 2018

В настоящее время я занимаюсь разработкой веб-приложения с помощью EF6 для управления данными.

Важно отметить ... отложенная загрузка включена, нет возможности фактически отключить ее (она была введена в приложение ранее. Мы говорим о устаревшем приложении) . Возвращаемые объекты, полученные из репозиториев, отображаются в модели представлений с помощью Automapper (7.0.1), которые затем передаются в представление. Так как я использую Automapper, я обнаружил, что лучший вариант для гарантии того, что мои свойства в моем источнике будут доступны, - это Eager-loading, используя метод Include(). Так что я смешиваю эти две логики - стремлюсь к загрузке, когда это возможно, остальные используют ленивую загрузку.

Так в чем же проблема?

Иногда мои навигационные свойства не загружаются должным образом и в моем с учетом view-моделей мои свойства равны нулю. Это происходит случайно. ОДНАКО , если я начинаю отладку (просто вставьте точку останова где-нибудь) , свойства отображаются правильно. Это что-то загадочное прячется за EF6? Может ли это быть проблема с Automapper? Каждое упоминание может помочь.


Сопоставленный объект UserEmailMessage, который включает в себя свойства навигации: Recipient, User и свойство с собственной ссылкой ReplyUserEmailMessage

 public class UserEmailMessage
    {
        //abbreviated for clarity
        public int UserEmailMessageId{ get; set; }
        public virtual User Recipient { get; set; }
        public virtual User Sender { get; set; }
        public virtual UserEmailMessage ReplyUserEmailMessage { get; set; }
    }

Entity User наследуется от IdentityUser, так как я использую ASP.NET Identity для управления членством.

public class User : IdentityUser<long, MyLogin, MyUserRole, MyClaim>
{
    //abbreviated for clarity
    public virtual List<UserEmailMessage> UserMessages { get; set; }
}

Запрос данных из моего хранилища

public UserEmailMessage TestEmailMessage(Expression<Func<UserEmailMessage, bool>> predicate)
        {
            return context.UserEmails.Where(predicate)
                .Include(p => p.Recipient).Include(p => p.Sender).Include(p => p.ReplyUserEmailMessage)
                .FirstOrDefault();
        }

Сопоставленный объект с заданным профилем Automapper

     public class EntityProfile : Profile
        {
            public EntityProfile()
            {
                CreateMap<UserEmailMessage, EmailMessageViewModel>()
                    .ForMember(dest => dest.RecipientId, source => source.MapFrom(sc => sc.Recipient.Id))
                    .ForMember(dest => dest.SenderEmail, source => source.MapFrom(sc => sc.Sender.Email))
                    .ForMember(dest => dest.SenderFirstName, source => source.MapFrom(sc => sc.Sender.FirstName))
                    .ForMember(dest => dest.SenderLastName, source => source.MapFrom(sc => sc.Sender.LastName))
                    .ForMember(dest => dest.RecipientEmail, source => source.MapFrom(sc => sc.Recipient.Email));
            }
        }

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

Иногда я получаю этот плохой результат в представлении (при использовании модели представления). Я заменяю пустые результаты явным словом empty . Только RecipientId включен в плохой результат.

//@Model.EmailMessageViewModel.RecipientId
RecipientId:182                         
//@Model.EmailMessageViewModel.SenderEmail                 
SenderEmail: empty
//@Model.EmailMessageViewModel.SenderFirstName      
SenderFirstName:empty
//@Model.EmailMessageViewModel.SenderLastName  
SenderLastName:empty
//@Model.EmailMessageViewModel.RecipientEmail
RecipientEmail:empty
...