实体框架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();
正如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中的构造函数被创建为这种奇怪的行为,其他一切都很好。