【问题标题】:EF6 automatically includes nested objectsEF6 自动包含嵌套对象
【发布时间】:2026-02-15 03:20:06
【问题描述】:

可能是一个简单的问题,但有些事情我无法理解。

我的结构 Bundle -> BundleMembers -> InsuranceTypes

当我从 BundleMembers 中检索单个记录时,我将 Bundle. EF6 自动将所有 BundleMembers 包含在 Bundle 中

例子:

public async Task<List<BundleMember>> GetBundleMembers(string userId, bool includeBundle, bool includeInsuranceTypes)
{
    var bundleMembers = db.BundleMembers.Where(m => string.Equals(m.UserId, userId, StringComparison.CurrentCultureIgnoreCase));
    if (includeBundle)
    {
        bundleMembers = bundleMembers.Include(o => o.Bundle);
    }
    if (includeInsuranceTypes)
    {
        bundleMembers = bundleMembers.Include(m => m.BundleMemberInsuranceType);
    }

    return await bundleMembers.ToListAsync();
}

我这样调用函数:

GetBundleMembers(_userManager.GetUserId(User), true, false)

为了避免这种情况,我是否必须访问 Bundle 中的数据?

编辑 1: 我的数据模型如下所示:

public class Bundle
    {
        public int BundleId { get; set; }

        public State State { get; set; }
        public ICollection<BundleMember> Members { get; set; }
        public ICollection<InviteLink> InviteLinks { get; set; }
        public string BundleName { get; set; }
        public string Description { get; set; }
        public string ImagePath { get; set; }

    }
    public enum State
    {
        NotApproved,
        Approved,
        Disabled,
        Rejected
    }

    public class BundleMember
    {
        public ApplicationUser User { get; set; }
        public string UserId { get; set; }
        public int BundleMemberId { get; set; }
        public int BundleId { get; set; }
        public Bundle Bundle { get; set; }
        public bool Admin { get; set; }
        public int Price { get; set; }
        public int Coverage { get; set; }
        public ICollection<BundleMemberInsuranceType> BundleMemberInsuranceType { get; set; }
    }

我没有包括 BundleMemberInsuranceTypeInviteLink,因为它们工作正常。

ApplicationDbContext 的相关部分:

public DbSet<Bundle> Bundles { get; set; }
public DbSet<BundleMember> BundleMembers { get; set; }

【问题讨论】:

  • 您确定附加数据没有被延迟加载吗?如果您已将属性标记为虚拟,那么它会在您请求时加载数据。 (调试器会做什么)
  • 因为我不能 100% 确定何时触发延迟加载,所以我不能说我确定这不是问题。成员属性是公共的非虚拟的,所以这不是问题。我可以从 Visual Studio 的输出窗口中看到,在没有调试器的情况下也正在检索数据。
  • 你能发布你的实体类,以及你的上下文类的相关部分吗?
  • @Frey:读取/访问属性时会触发延迟加载。在您的情况下,调试器很可能正在访问它。检查调用的 SQL 语句,以确定它是否延迟加载以及何时加载
  • 上下文中没有其他数据。由于 includeBundles 设置为 true,因此您的上下文中同时拥有 Bundles 和 BundleMembers(.Include() 所做的只是将相关条目加载到上下文中)。然后关系修正根据 FK 设置所有条目的导航属性。要让你的包没有 BundleMembers,请使用新的上下文(将成员加载到内存中,然后在另一个上下文中不包含包含的包)或首先分离所有成员并自己设置导航属性。

标签: asp.net asp.net-mvc entity-framework asp.net-core


【解决方案1】:

按照 cmets 的建议:

所描述的行为实际上是预期的。由于includeBundle 设置为true,Bundles 和引用的BundleMembers 都在上下文中,并且关系修复将根据FK 关系设置所有导航属性。

显然,这在BundleMembersBundles 和从BundlesBundleMembers 都有效,因为.Include 只不过是创建SQL 语句以将相关条目加载到上下文中以及关系修复剩下的会做。

要让Bundles 没有BundleMembers,您必须在没有BundleMembers 的上下文中加载它们并自己设置导航属性(EF 将始终设置直接和反向导航属性)。为了做到这一点,主要有两种方式:

  • 要么在没有先前加载的BundleMembers 的情况下将您的包加载到新的上下文中(最佳实践是将它们加载到内存中,因为 EF 导航属性是由于预先加载而加载的;您可以将条目附加到两个上下文和将抛出异常)或

  • 在将 Bundles 加载到其中之前,将您的 BundleMembers 从上下文中分离出来。

【讨论】: