实体框架6导航属性加载不起作用

本文关键字:加载 不起作用 属性 导航 框架 实体 | 更新日期: 2023-09-27 18:25:41

这个奇怪的问题已经困扰了好几个小时。由于某种原因,实体框架不会加载这种1对多关系的导航属性,即使生成的SQL似乎是正确的,外键从SubItems到FrontPageItems:都存在

CONSTRAINT [FK_dbo.SubItems_dbo.FrontPageItems_FrontPageItemId] 
    FOREIGN KEY ([FrontPageItemId]) 
        REFERENCES [dbo].[FrontPageItems] ([Id]) ON DELETE CASCADE

我已尝试用以下内容加载所有头版项目:_repo.Get();,但是即使SubItem表包含引用FronPageItems表的外键,也不会加载导航属性。

public class FrontPageItem : Logger, IEntity, IIsPublished
{
    public FrontPageItem()
    {
        SubItems = new HashSet<SubItem>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsPublished { get; set; }
    public virtual ICollection<SubItem> SubItems { get; set; }
}
    public class SubItem : Logger, IEntity, IIsPublished
{
    public SubItem()
    {
        FrontPageItem = new FrontPageItem();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string YoutubeUrl { get; set; }
    public virtual FrontPageItem FrontPageItem { get; set; }
    public int FrontPageItemId { get; set; }
    public bool IsPublished { get; set; }
}
public class SampleContext : IdentityDbContext<ApplicationUser>
{
    // throwIfV1Schema is used when upgrading Identity in a database from 1 to 2.
    // It's a one time thing and can be safely removed.
    public SampleContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }
    public static SampleContext Create()
    {
        return new SampleContext();
    }
    // Define you conceptual model here. Entity Framework will include these types and all their references. 
    public IDbSet<FrontPageItem> FrontPageItem { get; set; }
    public IDbSet<SubItem> SubItems { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // The DateTime type in .NET has the same range and precision as datetime2 in SQL Server.
        // Configure DateTime type to use SQL server datetime2 instead.
        modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
        base.OnModelCreating(modelBuilder);
    }
}

顺便说一句,如果我删除子项中的foreignkey属性,它会起作用

public int FrontPageItemId{get;set;}

我已经尝试过像这样的热切加载:

        var frontPageItems = _repo.AsQueryable().Include(o => o.SubItems).ToList();

实体框架6导航属性加载不起作用

正如DavidG所提到的,延迟加载是默认的en EF。这意味着只有当您实际使用这些属性时,才会加载它们。

为了强制包含子项,您可以使用类似的包含

FrontPageItem.Include(x => x.SubItems).FirstOrDefault().

这里的FrontPageItem是您的dbset。如果你这样查询它,它会加载第一个首页项目,所有子项目都连接到它

更新:如果你严格遵守约定,你不需要这样做,但如果你的属性有不同的名称或想要有一个明确的外键,那么你可以像这个一样配置外键

modelBuilder.Entity<SubItem>() 
  .HasRequired(t => t.FrontPageItem) 
  .WithMany(t => t.SubItems) 
  .HasForeignKey(d => d.FrontPageItemId) 
  .WillCascadeOnDelete(true);

LazyLoadingEnabled必须为true,而不是false:

context.Configuration.LazyLoadingEnabled = true;如果根本不设置LazyLoadingEnabled,则默认值为true。

并且SubItems属性必须是虚拟的,才能对此属性启用延迟加载。

也可以直接在查询中包含属性。您还需要使用modelBuilder 设置FK

    modelBuilder.Entity<SubItem>() 
  .HasRequired(t => t.FrontPageItem) 
  .WithMany(t => t.SubItems) 
  .HasForeignKey(d => d.FrontPageItemId) 
  .WillCascadeOnDelete(true);

或者通过使用属性配置关系

[ForeignKey("FrontPageItem")]
 public virtual FrontPageItem FrontPageItem { get; set; }
    public SubItem()
{
    FrontPageItem = new FrontPageItem();
}

是问题所在。由于某种原因,SubItem中的构造函数被创建为这种奇怪的行为,其他一切都很好。