2012-04-22 12 views
0

エンティティフレームワークコードファーストを使用してエンティティを定義しましたが、オプションの親ノードフィールドがあります。ヌルの親ノード値は、エンティティのノードがルートにあることを意味します。同じ親の下に複数の子供がいます。 DB初期化子で外部キーの変更は、最初にEF4コードには影響しません

Class ContentDescriptor 
{ 
    virtual ObjectId ParentObjectId{get;set;} 
} 

は:

DBContext.ContentDescriptors.Add(contentDescriptor); 
    contentDescriptor.ParentObjectId = ObjectIdFactory.Save(parent); 

ObjectIdFactory.SaveチェックをDBContext.ObjectId.Localにエントリがある場合、その後:

HasOptional(contentDescriptor => contentDescriptor.ParentObjectId).WithOptionalDependent() 
    .Map(m => m.MapKey("ParentObjectId")); 

ナビゲーションプロパティは、以下のように割り当てられていますDBContext.ObjectId、メモリまたはDBにレコードがない場合は、挿入して結果を返します。

ただし、新しいノードがコンテキストに追加されると、親の最初の子だけが正しく保存されます。 2番目以降の子は、ローカルの親の子として表示されても、ルートに追加されます。エンティティが追加されているときに、フレームワークが外部キーの更新クエリを生成できないように見えます。

私walkaroundは、エンティティ内の外部キーを公開し、手動で外部キーを割り当てることですが、よりエレガントな解決策がある場合、私は疑問に思って:

HasOptional(contentDescriptor => contentDescriptor.ParentObjectId).WithMany(). 
HasForeignKey(c=>c.ParentObjectIdRaw); 
Property(c => c.ParentObjectIdRaw).HasColumnName("ParentObjectId"); 


contentDescriptor.ParentObjectIdRaw = contentDescriptor.ParentObjectId.ObjectIdId; 

答えて

0

これは通常、(私にとって最高の作品何です注:私は4.3を使用しています、私はそれがはるかに異なっているとは思わないが、わからない)...
(私は擬似Node自己参照エンティティのために使用している、

public class Node 
{ 
    public int NodeID { get; set; } 
    public string Name { get; set; } 
    public virtual Node Parent { get; set; } 
    public virtual ICollection<Node> Children { get; set; } 
} 

...

modelBuilder.Entity<Node>() 
    .HasOptional(n => n.Parent) 
    .WithMany(n => n.Children); 

...あなたの実装の問題は通常、1対1の関係のためのWithOptionalDependentかもしれません(あなたが言ったように1対多の関係を持っています)。用法側で

...

using (var db = new UserDbContext()) 
{ 
    var root = new Node { Name = "root" }; 
    var node = new Node { Name = "first", Parent = root }; 
    var child1 = new Node { Name = "child1", Parent = node }; 
    var child2 = new Node { Name = "child2", Parent = node }; 
    db.Nodes.Add(child1); 
    db.Nodes.Add(child2); 
    db.SaveChanges(); 
    foreach (var n in db.Nodes.Include(x => x.Parent)) 
     Console.WriteLine("node: {0}, {1}, {2}, {3}, {4}", n.Name, n.NodeID, n.Parent != null ? n.Parent.Name : "", n.Parent != null ? n.Parent.NodeID : 0, n.Children != null ? n.Children.Count : 0); 
} 

...私の知る限り、あなただけの(自動的に親を追加)子供を追加する必要があります。または、Childrenを使用して別の方法で追加することができます。親ノードに子を追加します。この場合、ルートのみを保存するだけで十分です。

これはあなたが持っているものを解決するかどうかはっきりしていません(私はあなたが何をしているのか正確にはわかりません)が、同じパターンであり、本当に親を救う必要はありません。これは任意の

+0

を助けSaveChanges()

希望に前だけで子供を救う基本的に他のすべてのエンティティがのObjectIdを持っていると私は不要導入したくないたObjectIdに関連するクエリに参加し、その親オブジェクトIDには、コレクションプロパティがありません。私はWithManyを試してナビゲーションプロパティを設定しましたが効果はありません。 –

+0

コレクションプロパティで何も追加されていない場合、追加のナビゲーションプロパティが追加されます(既存のリレーションシップの他の部分)。とにかく、 '.WithMany()'を使用してコレクションを削除しても、何も変更されません。そして、私の側では、すべてのノードが正しく追加されます。そのメソッドの内部で何もし​​ていないことを確認してください。 – NSGaga

+0

私のエンティティの関係は少し異なります。いくつかのオブジェクトタイプのみがツリー構造であり、他のオブジェクトはフラットリストまたは他の構造を有することができる。ツリー構造のオブジェクトタイプは、ContentDescriptorテーブルに保存された関係を持ちます。そして、パートナーからの私のすべてのルックアップはObjectIdに基づいているため、ParentObjectIdはキャッシュ列から親子関係を定義する唯一の列に移動しました。 ObjectId.ParentObjectId列を追加すると多くの記憶領域が浪費され、ContentDescriptor.ParentContentDescriptorは検索に非効率的になります。 –

関連する問題