У меня проблема, очень похожая на те, которые упомянуты в следующих вопросах:
Почему свойство навигации Entity Framework имеет значение null?
Почему свойство навигации EF возвращает ноль?
В моем случае поворот сюжета заключается в том, что свойства коллекции навигации заполняются EF, но только после того, как я запросил DbSet<T>
свойства зависимых типов в DbContext
. Чтобы прояснить ситуацию, вот как настроена моя модель:
[Table(nameof(Composer))]
internal class ComposerRelationalDto : RelationdalDtoBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public virtual ICollection<NameRelationalDto> LocalizedNames { get; set; } = new HashSet<NameRelationalDto>();
public virtual ICollection<ArticleRelationalDto> Articles { get; set; } = new HashSet<ArticleRelationalDto>();
}
[Table(nameof(ComposerName))]
internal class NameRelationalDto : RelationdalDtoBase
{
[Key]
public long Id { get; set; }
[Required]
[ForeignKey(nameof(Composer))]
public Guid Composer_Id { get; set; }
public ComposerRelationalDto Composer { get; set; }
}
[Table(nameof(ComposerArticle))]
internal class ArticleRelationalDto : RelationdalDtoBase
{
[Key]
public long Id { get; set; }
[Index]
public Guid StorageId { get; set; }
[Required]
[ForeignKey(nameof(Composer))]
public Guid Composer_Id { get; set; }
public ComposerRelationalDto Composer { get; set; }
[Required]
[MaxLength(5)]
public string Language { get; set; }
}
В соответствующем репозитории я фильтрую ComposerRelationalDto
объекты по их именам:
DbContext.Set<NameRelationalDto>().Where(nameWhereClause).GroupBy(n => n.Composer_Id).Select(group => group.FirstOrDefault().Composer)
Набор ComposerRelationalDto
s содержит пустые коллекции для свойств Articles
и LocalizedNames
, даже если данные были правильно сохранены в базе данных. Однако если я загружаю все DTO типа ArticleRelationalDto
и NameRelationalDto
в QuickWatch во время отладки , , тогда тот же фильтр больше не возвращает пустые коллекции, и все соответствующие объекты присутствуют в свойствах коллекции. .
То, что я до сих пор пробовал, было
включить отложенную загрузку и явное создание прокси
настроить отношения один-ко-многим вручную:
modelBuilder.Entity<ComposerRelationalDto>().HasMany(c => c.LocalizedNames).WithRequired(n => n.Composer).HasForeignKey(n => n.Composer_Id);
modelBuilder.Entity<ComposerRelationalDto>().HasMany(c => c.Articles).WithRequired(a => a.Composer).HasForeignKey(a => a.Composer_Id);
и, наконец, я только что попробовал поиграться с DbQuery<T>.Include()
методом DbContext.Set<ComposerRelationalDto>().Include(c => c.Articles)
, который, к сожалению, выдает исключение ArgumentNullException из одного из внутренних методов, которые он вызывает.
По сути, все исправления или обходные пути, которые я пробовал, не помогли, поэтому я должен обратиться за дополнительной помощью.
Редактировать :
Я изменил свойство Composer зависимых типов, чтобы оно было виртуальным. Однако проблема сохраняется.
После использования .Select(group => group.FirstOrDefault().Composer).Include(c => c.Articles).Include(c => c.LocalizedNames)
теперь я больше не получаю ArgumentNullException
(может быть, я получаю ArgumentNullException
, потому что я изначально использовал .Include()
в QuickWatch?), А скорее MySqlException
: неизвестный столбец ' Join2.Id 'в' списке полей '; Словарь данных содержит Ключ: «Код ошибки сервера» Значение: 1054. Также сгенерированный SQL смехотворно велик и едва читаем.