簡體   English   中英

實體框架:將現有子POCO添加到新的父POCO,在DB中創建新子項

[英]Entity Framework: adding existing child POCO to new Parent POCO, creates new child in DB

我想在斷開連接(從上下文)模式中使用Entity Framework POCO。 在我的場景中,我正在創建一個新的Parent對象,並希望將現有的子對象附加到它,然后將其保存到db。
下面的代碼在保存新的學生記錄時不合需要地插入新的課程記錄,而我希望現有的課程記錄鏈接到新的學生記錄。

我如何在Entity Framework中執行此操作...

  • 對象可以與上下文斷開連接。 (即在一個上下文中查詢,然后保存在不同的上下文中)
  • 我不需要從數據庫中重新查詢子記錄,這樣我就可以在保存到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;
    }
}

我相信實現這一目標的方法很少。 您可以按以下方式指定課程實體未更改而不是添加:

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

或者指導您的上下文,您正在使用現有實體:

ctx.Courses.Attach(course);

更多信息: http//msdn.microsoft.com/en-us/data/jj592676.aspx

編輯

我的解決方案中有一些運行樣本,我驗證它們按預期工作。 在所有情況下,我們在數據庫中都有發布者記錄,ID = 2,Name =“Addison Wesley”(與示例無關,但只是為了好的衡量標准)。

方法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 - 使用Attach方法

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,它必須根據NavigationPropertyName +'Id'約定命名,由EF自動拾取:

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

我在這里使用EF5 Code First,但它與POCO非常相似。

實體框架不允許跨越上下文的關系。

如果您在相同的使用聲明中放置課程閱讀並將課程連接到學生,它將起作用。

我也嘗試過它為我工作的第二個選項。 我確實喜歡先在對象級別發生的parent-> child關系並保存到db。 也許我應該刪除EF生成的實體之間的所有關系,並自己手動控制它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM