3

ナビゲーション プロパティを EF Code First で動作させるのが非常に困難です。抽象化された例として、次のものがあります。

public class Parent{
    public int ParentID {get; set;}
    public virtual List<NamedChild> Children {get; set;}
    public Parent(){}
    public void Init(int ParentID, List<UnnamedChild> Children){
        this.ParentID = ParentID;
        this.Children = Children.ConvertAll(x => new NamedChild(x, ""));
    }
}

public class NamedChild{
    public int ChildID {get; set;}
    public string Name {get; set;}
    public NamedChild(UnnamedChild c, string Name){
        this.ChildID = c.ChildID;
        this.Name = Name;
    }
}

public class UnnamedChild{
    public int ChildID {get; set;}
    public UnnamedChild(int ChildID){
        this.ChildID = ChildID;
    }
}

そしてその後…

List<UnnamedChild> children = GetChildrenFromSomewhere();
Parent p = db.Parents.Create();
p.Init(1, children);
db.Parents.Add(p);
db.SaveChanges();

デバッグ中の場合、現在の DbSet を調べると、親が 1 つあり、その「子」プロパティが 2 つの NamedChild のリストに設定されていることがわかります。これでいい、こうあるべきだ。ただし、プログラムを停止して再実行すると、DbSet を調べると、まだ親が 1 つありますが、その「子」プロパティは null に設定されています。

要約すると、保存した直後は値が正しいのですが、DB コンテキストを再ロードするとすぐにそれらの値が失われます (null)。LazyLoading を有効にして最新の EF を実行しています。

.Include() を使用すると、これらの null 値に適切な NamedChild リストが設定されますが、LazyLoading を使用するにはこれが必要です。

4

2 に答える 2

1

技術的には問題ではないと思いますが、EF はICollections他のリスト/配列型よりも優先されるように思われることに気付きました。試す:

public virtual ICollection<NamedChild> Children {get; set;}

また、カスタム コンストラクターで何を達成しようとしているのか、少し混乱しています。インスタンスのプロパティを初期化しているだけのようです。その場合、カスタム コンストラクターは必要ありません。クラスの初期化構文を使用するだけです。

x => new NamedChild { ChildId = x.ChildId, Name = "" }
于 2013-07-08T18:38:26.620 に答える