В настоящее время я занимаюсь разработкой веб-приложения с помощью 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