2013-01-13 3 views
7

Im接続されていない(コンテキストから)モードでEntity Framework POCOを使用したいです。私のシナリオでは、新しいParentオブジェクトを作成していて、それに既存の子オブジェクトをアタッチして、それをdbに保存します。
以下のコードは、新しい生徒記録を保存するときに、新しい生徒記録にリンクされている既存の生徒記録を残したいときに、新しい生徒記録を挿入することが望ましくありません。Entity Framework:新しい親POCOに既存の子POCOを追加し、DB内に新しい子を作成します。

私はオブジェクトが文脈から切り離すことができます...

  • Entity Frameworkの中でこれを行うことができますどのように。 (つまり、あるコンテキストでクエリを実行して別のコンテキストで保存した場合)
  • データベースに子レコードを再クエリする必要はありません.dbに保存するときに親レコードに追加できます。私は実際にメモリ内のオブジェクトとして既に持っているときに、DBへの余分な移動を避けたいと思っています。

このページには、以下のコードは、コンテキストを渡る関係を許可していませんhttp://entityframeworktutorial.net/EF4_EnvSetup.aspx#.UPMZ4m-UN9Y

class Program 
{ 
    static void Main(string[] args) 
    { 

     //get existing course from db as disconnected object 
     var course = Program.getCourse(); 

     //create new student 
     var stud = new Student(); 
     stud.StudentName = "bob"; 

     //assign existing course to the student 
     stud.Courses.Add(course); 

     //save student to db 
     using (SchoolDBEntities ctx = new SchoolDBEntities()) 
     { 
      ctx.Students.AddObject(stud); 
      ctx.SaveChanges(); 
     } 
    } 

    static Course getCourse() 
    { 
     Course returnCourse = null; 

     using (var ctx = new SchoolDBEntities()) 
     { 
      ctx.ContextOptions.LazyLoadingEnabled = false; 
      returnCourse = (from s in ctx.Courses 
          select s).SingleOrDefault(); 
     } 

     return returnCourse; 
    } 
} 

答えて

17

私はこれを達成する方法はほとんどないと考えています。

ctx.Entry(course).State = EntityState.Unchanged; 

または既存のエンティティで作業していることを、あなたのコンテキストを指示します:ここに

ctx.Courses.Attach(course); 

さらに詳しい情報: http://msdn.microsoft.com/en-us/data/jj592676.aspxを あなたは、企業がこれらの線に沿って、そのままではなく、追加されていることコースを指定することができます

EDIT

私の解決策から実行中のサンプルがいくつかあり、期待どおりに動作することを確認しました。 ID = 2、Name = "Addison Wesley"のデータベースにPublisherレコードがあります(この例とは無関係ですが、適切な対策のためだけです)。

アプローチ1 - 設定するエンティティの状態

using (var context = new Context()) 
{ 
    var book = new Book(); 
    book.Name = "Service Design Patterns"; 
    book.Publisher = new Publisher() {Id = 2 }; // Only ID is required 
    context.Entry(book.Publisher).State = EntityState.Unchanged; 
    context.Books.Add(book); 
    context.SaveChanges(); 
} 

アプローチ2 -

using (var context = new Context()) 
{ 
    var book = new Book(); 
    book.Name = "Service Design Patterns"; 
    book.PublisherId = 2; 
    context.Books.Add(book); 
    context.SaveChanges(); 
} 
外部キーの値を設定する - 方法

using (var context = new Context()) 
{ 
    var book = new Book(); 
    book.Name = "Service Design Patterns";     
    book.Publisher = new Publisher() { Id = 2 }; // Only ID is required 
    context.Publishers.Attach(book.Publisher); 
    context.Books.Add(book); 
    context.SaveChanges(); 
} 

アプローチ3を取り付けて使用します私は余分な財産発行者IDを追加する必要が動作するように、この最後のアプローチのために、それはauotmatically EFによってピックアップされるNavigationPropertyName +「ID」規則に従って命名される

があります

public int PublisherId { get; set; } 
public Publisher Publisher { get; set; } 

私はここにEF5コードを使用していますまず、POCOと非常によく似ています。

+0

2番目のオプションはほとんど機能しますが、「オブジェクトコンテキストに既に存在するため、オブジェクトを追加できません」というメッセージが表示されます。 "ctx.Students.AddObject(stud);"のエラーライン。私はまだ「スタッド。コース。追加(コース)」をやっている間、これをやれないと思います。その前に 。スタッドオブジェクトでコースコレクションを引き続き使用したいと思います。 – MakkyNZ

+0

さて、私はそれをテストするのに便利なソリューションはありませんが、まずそれを添付して、それを学生に追加しようとします。うまくいけば、それはEFによって「追加された」とマークされません。 –

+0

これは本当に理想的ではありません。私はそれがまだdbに保存する準備ができていない可能性がありますので、最初にオブジェクトレベルで親子関係が起こってほしいです。 EFが生成し、手動でこれを自分自身で制御するエンティティ間の関係をすべて削除する必要があるかもしれません。 – MakkyNZ

0

Entity Frameworkのに基づいてデータベースダイアグラムを示しています。

コースの読書を配置し、同じusingステートメント内でコースを生徒に接続すると、それは機能します。

0

私も2番目の選択肢を試してみました。私は親と子の関係が最初にオブジェクトレベルで起こっていて、dbに保存するのが好きでした。 EFが生成し、手動でこれを自分自身で制御するエンティティ間の関係をすべて削除する必要があるかもしれません。

関連する問題