0

私が経験したLinqのこの動作を理解する必要があります。「パッケージ」をデータベースに保存しています。パッケージは親と子を持つことができるため、グラフ構造です。次の方法を使用して、ルート パッケージを取得します。次に、子とその子などを取得する必要があります。

ルートパッケージの取得方法

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 の Children リストに追加するたびに、CHILD_B にも追加されていることがわかりました。各パッケージには固有のパッケージ ID があるため、パッケージがまったく同じではないことは確かです。Children リストへのポインターまたは参照が完全に混同されているようですが、これはなぜでしょうか? これに光を当ててくれてありがとう。

4

0 に答える 0