这个奇怪的问题困扰了几个小时。由于某种原因,实体框架不会加载此1对多关系的导航属性,即使生成的SQL似乎正确,也存在从SubItems到FrontPageItems的外键:
LINENO 0
我尝试加载所有frontpageitems:
CONSTRAINT [FK_dbo.SubItems_dbo.FrontPageItems_FrontPageItemId]
FOREIGN KEY ([FrontPageItemId])
REFERENCES [dbo].[FrontPageItems] ([Id]) ON DELETE CASCADE
,但即使_repo.Get();
表包含引用SubItem
表的外键,也不会加载导航属性。
FronPageItems
如果我删除SubItem中的foreignkey属性,它可以工作:
public int FrontPageItemId {get;组; }
我尝试过像这样的包含加载:
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); } }
答案 0 :(得分:2)
正如DavidG所提到的,延迟加载是默认的en EF。这意味着只有在您实际使用它们时才会加载属性。
为了强制包含子项,你可以使用像这样的
FrontPageItem.Include(x => x.SubItems).FirstOrDefault().
FrontPageItem这里是你的dbset。如果您这样查询,它将加载第一个frontpageitem,其中所有子项都连接到它。
更新:如果您严格遵守惯例,则无法执行此操作,但如果您的属性具有不同的名称或希望拥有明确的外键,则可以配置像这样的外键
modelBuilder.Entity<SubItem>()
.HasRequired(t => t.FrontPageItem)
.WithMany(t => t.SubItems)
.HasForeignKey(d => d.FrontPageItemId)
.WillCascadeOnDelete(true);
答案 1 :(得分:0)
LazyLoadingEnabled
必须是真的,而不是假的:
context.Configuration.LazyLoadingEnabled = true
;
如果您根本没有设置LazyLoadingEnabled,则默认为true。
SubItems
属性必须是虚拟的才能为此属性启用延迟加载。
或者您可以直接在查询中包含该属性。
您还需要使用FK
modelBuilder
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; }
答案 2 :(得分:0)
public SubItem()
{
FrontPageItem = new FrontPageItem();
}
是问题所在。出于某种原因,SubItem中的构造函数创建了这种奇怪的行为,其他一切都很好。