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

时间:2015-12-04 09:31:43

标签: c# asp.net-mvc entity-framework

这个奇怪的问题困扰了几个小时。由于某种原因,实体框架不会加载此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);
    }
}

3 个答案:

答案 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中的构造函数创建了这种奇怪的行为,其他一切都很好。