实体框架不会填充集合属性

时间:2018-07-03 19:12:48

标签: c# entity-framework entity-framework-6

我遇到的问题与这些问题中提到的问题非常相似:

Why is Entity Framework navigation property null?

Why EF navigation property return null?

在我看来,情节的转折点在于导航集合属性是由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的集合具有ArticlesLocalizedNames属性的空集合,即使数据已正确保存在数据库中也是如此。但是,如果我在QuickWatch while debugging中加载类型为ArticleRelationalDtoNameRelationalDto的所有DTO,则然后同一过滤器将不再返回空集合,并且集合中存在所有相关对象属性

到目前为止,我一直在尝试

  1. 显式启用延迟加载和代理创建

  2. 手动配置一对多关系:

    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);
    
  3. 最后我只是尝试摆弄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(也许是因为我最初在QuickWatch中使用ArgumentNullException是因为得到了.Include()?),而是MySqlException:“字段列表”中的未知列“ Join2.Id”;数据字典中包含关键字:“服务器错误代码”,值:1054。the generated SQL也非常大,几乎看不清。

1 个答案:

答案 0 :(得分:0)

我知道了。它是类声明上的internal访问修饰符。真可惜,因为我真的想使解决方案的其余部分完全不依赖数据库(因此,首先非常规地将DTO用于代码,而不是注释中已经指出的实际实体),并且我想强制执行此操作严格地。

无论如何,我使用访问修饰符进行了更多操作,并且只能通过使用public构造函数使它们成为internal protected来限制数据库对象的可见性。涉及internal的类和ctor可见性的任何其他组合导致问题再次出现。 InternalsVisibleTo也没有运气。

这个问题-Entity Framework Code First internal class - is it possible?-似乎表明使用内部类对于EF来说应该不是问题,但是看来这毕竟是一个问题。如果不是那样的话(朱莉·勒曼的回答可以追溯到2011年),那就是现在。我目前正在使用EF 6.2.0。