8

切断された (コンテキストからの) モードで Entity Framework POCO を使用したいと考えています。私のシナリオでは、新しい親オブジェクトを作成していて、既存の子オブジェクトをそれにアタッチしてからデータベースに保存したいと考えています。
以下のコードは、既存の Course レコードを新しい Student レコードにリンクしたいのに、新しい Student レコードを保存するときに、望ましくない新しい Course レコードを挿入します。

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;
    }
}
4

3 に答える 3

19

これを達成する方法はいくつかあると思います。次の行に沿って、コースエンティティを追加するのではなく変更しないように指定できます。

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

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

ctx.Courses.Attach(course);

詳細はこちら: http: //msdn.microsoft.com/en-us/data/jj592676.aspx

編集

私のソリューションからいくつかの実行中のサンプルがあり、それらが期待どおりに機能することを確認しました。すべての場合において、データベースに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.Publisher = new Publisher() { Id = 2 }; // Only ID is required
    context.Publishers.Attach(book.Publisher);
    context.Books.Add(book);
    context.SaveChanges();
}

アプローチ3-外部キー値の設定

using (var context = new Context())
{
     var book = new Book();
     book.Name = "Service Design Patterns";
     book.PublisherId = 2; 
     context.Books.Add(book);
     context.SaveChanges();
}

この最後のアプローチを機能させるには、追加のプロパティPublisherIdを追加する必要がありました。これは、EFが自動的に取得するNavigationPropertyName+'Id"規則に従って名前を付ける必要があります。

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

ここではEF5CodeFirstを使用していますが、POCOと非常によく似ています。

于 2013-01-13T20:52:46.830 に答える
0

私はまた、それが私のために働いた2番目のオプションを試しました. 親から子への関係が最初にオブジェクト レベルで発生し、db に保存するのが好きでした。おそらく、EF が生成するエンティティ間のすべての関係を削除し、これを自分で手動で制御する必要があります。

于 2014-08-03T14:07:48.967 に答える
0

Entity Framework では、コンテキストをまたがるリレーションシップは許可されていません。

コースを読み、コースを学生に接続することを同じ using ステートメント内に配置すると、うまくいきます。

于 2013-01-13T20:48:43.390 に答える