我需要了解我经历过的 Linq 的这种行为。我将“包”存储在数据库中。包可以有父母和孩子,所以它是一个图结构。使用以下方法我获取根包,然后我需要获取孩子,以及他们的孩子等等..
获取root包的方法
var rootPack = (from p in context.Packages
    //several joins emitted for clarity
    where p.PackageID == parentId
    select new PackageModel
        {
            PackageId = p.PackageID,
            TagId = p.TagID
            //rest of the properties have been emitted for clarity
         }).FirstOrDefault();
if (rootPack != null)
{
    rootPack.Children = new List<PackageModel>();
    var fullStructure = GetChildPackages(rootPack, rootPack);
}
以下方法引起了我的问题,这是一种工作形式:
GetChildPackages - 工作表
private PackageModel GetChildPackages(PackageModel package, PackageModel parentPackage = null)
{
        var innerContext = new DbDataContext(ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString);
        var children = (from p in innerContext.Packages
                            //several joins emitted for clarity
                            where p.ParentPackageID == package.PackageId
                            select new PackageModel
                            {
                                PackageId = p.PackageID,
                                Parent = parentPackage,
                                //rest of the properties have been emitted for clarity              
                            }).ToList();
        //get all children
        foreach (var child in children)
        {
            child.Children = new List<PackageModel>();
            package.Children.Add(GetChildPackages(child, package));
        }
        return package;
}
请注意,在我选择它之后,我在 foreach 循环中初始化了每个孩子的孩子列表。我曾经在查询中使用所有其他属性对其进行初始化。
假设我加载了这个结构:
                ROOTPACKAGE
               /           \
        CHILD_A             CHILD_B
        /   |
CHILD_A1    CHILD_A2
我列出的代码可以很好地加载这个结构,但是如果我在 Linq 查询中初始化 Children 列表,就会崩溃。而不是 CHILD_B 没有孩子,它将有 CHILD_A1 和 CHILD_A2。CHILD_A 也会有这些孩子。在调试器中,我可以看到每次我添加到 CHILD_A 的子列表中 - 它也被添加到 CHILD_B。由于每个包都有唯一的 packageid,我确信这些包不一样。似乎指向 Children 列表的指针或引用完全混淆了 - 但这是为什么呢?感谢您对此有所了解。