简体   繁体   English

实体框架:将现有子POCO添加到新的父POCO,在DB中创建新子项

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

Im wanting to use Entity Framework POCO in a disconnected (from context) mode. 我想在断开连接(从上下文)模式中使用Entity Framework POCO。 In my scenario I'm creating a new Parent object and want to attach an existing child object to it and then save it to the db. 在我的场景中,我正在创建一个新的Parent对象,并希望将现有的子对象附加到它,然后将其保存到db。
The code below undesirably inserts a new Course record when saving a new Student record, when instead I want the existing Course record linked to the new Student record. 下面的代码在保存新的学生记录时不合需要地插入新的课程记录,而我希望现有的课程记录链接到新的学生记录。

How can I do this in Entity Framework where... 我如何在Entity Framework中执行此操作...

  • the objects can be disconnected from the context. 对象可以与上下文断开连接。 (ie Queried in one context and then saved in a different context) (即在一个上下文中查询,然后保存在不同的上下文中)
  • I dont need to re-query the child record from the DB just so I can attach it to the parent when I'm saving to db. 我不需要从数据库中重新查询子记录,这样我就可以在保存到db时将其附加到父级。 I really want to avoid doing extra trips to the db when I already have it as an object in memory. 当我已经将它作为内存中的对象时,我真的想避免额外访问数据库。

This page shows a database diagram that the code below is based on http://entityframeworktutorial.net/EF4_EnvSetup.aspx#.UPMZ4m-UN9Y 此页面显示了一个数据库图表,下面的代码基于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;
    }
}

I believe there are few ways of accomplishing this. 我相信实现这一目标的方法很少。 You can specify that course entity is unchanged rather than added, along these lines: 您可以按以下方式指定课程实体未更改而不是添加:

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

Or instruct your context, that you are working with existing entity: 或者指导您的上下文,您正在使用现有实体:

ctx.Courses.Attach(course);

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

EDIT 编辑

There are some running samples from my solution, I verified they work as expected. 我的解决方案中有一些运行样本,我验证它们按预期工作。 In all cases we have Publisher record in database with ID = 2 and Name = "Addison Wesley" (irrelevant to the example, but just for good measure). 在所有情况下,我们在数据库中都有发布者记录,ID = 2,Name =“Addison Wesley”(与示例无关,但只是为了好的衡量标准)。

Approach 1 - Setting Entity State 方法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();
}

Approach 2 - Using Attach method 方法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();
}

Approach 3 - Setting Foreign Key value 方法3 - 设置外键值

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

For this last approach to work I needed to add extra property PublisherId, it has to be named according to NavigationPropertyName + 'Id" convention to be picked up by EF auotmatically: 对于这最后的工作方法,我需要添加额外的属性PublisherId,它必须根据NavigationPropertyName +'Id'约定命名,由EF自动拾取:

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

I am using here EF5 Code First, but it is very similar to POCO. 我在这里使用EF5 Code First,但它与POCO非常相似。

Entity Framework does not allow relationships that cross contexts. 实体框架不允许跨越上下文的关系。

If you place the reading of the course and connecting the course to the student within the same using statement, it would work. 如果您在相同的使用声明中放置课程阅读并将课程连接到学生,它将起作用。

I also tried the second option it worked for me. 我也尝试过它为我工作的第二个选项。 I did like the parent->child relationship happening at an object level first and save to db. 我确实喜欢先在对象级别发生的parent-> child关系并保存到db。 Maybe I should just remove all the relationships between the entities that EF generates and manually control this myself. 也许我应该删除EF生成的实体之间的所有关系,并自己手动控制它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体框架通过多对多关系将现有子级添加到新父级 - Entity Framework adding existing Child to a new Parent on a many to many relation 新子项在Entity Framework 4中插入现有父项 - New child inserts existing parent in Entity Framework 4 实体框架:使用新的父对象更新现有的子对象 - Entity Framework : Updating an existing child object with a new parent object Silverlight&RIA&POCO:插入两个新的子实体时,SubmitOperationFailed。 存在具有相同ID的实体 - Silverlight & RIA & POCO: SubmitOperationFailed when INSERTING two new child entities. An entity with the same ID exists 向我的Entity Framework POCO类添加功能 - Adding functionality to my Entity Framework POCO classes 创建一个与现有父级有关系的新子级,在dbContext.save()处创建一个新父级。 - Creatng a new child with a relation to an existing parent creates a new parent at dbContext.save() 为什么在我的实体框架中添加子元素会尝试插入新的父元素? - Why does adding a child element to my entity framework try and insert a new parent? 实体框架中的POCO支持 - POCO Support in the Entity Framework 实体框架POCO中的枚举 - Enum in an Entity Framework POCO 什么是POCO的实体框架 - what is Entity Framework with POCO
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM