我需要了解我经历过的 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 列表的指针或引用完全混淆了 - 但这是为什么呢?感谢您对此有所了解。