实体框架:将现有的POCO添加到新的父POCO中,在DB中创建新的子节点 [英] Entity Framework: adding existing child POCO to new Parent POCO, creates new child in DB

查看:148
本文介绍了实体框架:将现有的POCO添加到新的父POCO中,在DB中创建新的子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要在断开连接(从上下文)模式中使用实体框架POCO。在我的情况下,我创建一个新的父对象,并希望附加一个现有的子对象,然后将其保存到db。

当保存新学生时,下面的代码不合需要地插入一个新的课程记录记录,而我想要现有的课程记录链接到新的学生记录。



如何在Entity Framework中执行此操作...




  • 对象可以与上下文断开连接。 (即在一个上下文中查询,然后保存在不同的上下文中)

  • 我不需要从DB重新查询子记录,所以我可以将其附加到父项, m保存到db。当我已经将其作为内存中的对象,我真的想避免对数据库进行额外的访问。



此页面显示了一个数据库图,其代码基于 http://entityframeworktutorial.net/EF4_EnvSetup.aspx#.UPMZ4m-UN9Y

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

//从db断开现有课程对象
var course = Program.getCourse();

//创建新学生
var stud = new Student();
stud.StudentName =bob;

//为学生分配现有的课程
stud.Courses.Add(course);

//将学生保存到db
使用(SchoolDBEntities ctx = new SchoolDBEntities())
{
ctx.Students.AddObject(stud);
ctx.SaveChanges();
}
}

static课程getCourse()
{
课程returnCourse = null;

使用(var ctx = new SchoolDBEntities())
{
ctx.ContextOptions.LazyLoadingEnabled = false;
returnCourse =(from ct 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的数据库中都有Publisher记录(与示例无关,但仅适用于较好的度量)。



方法1 - 设置实体状态

  using(var context = new Context())
{
var book = new Book();
book.Name =服务设计模式;
book.Publisher = new Publisher(){Id = 2}; //只需要ID
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 =服务设计模式;
book.Publisher = new Publisher(){Id = 2}; //只需要ID
context.Publishers.Attach(book.Publisher);
context.Books.Add(book);
context.SaveChanges();
}

方法3 - 设置外键值 (var context = new Context())
{
var book = new Book();


$ b

  
book.Name =服务设计模式;
book.PublisherId = 2;
context.Books.Add(book);
context.SaveChanges();
}

对于最后一种工作方式,我需要添加额外的属性PublisherId,它有根据NavigationPropertyName +'Id约定命名为EF自动提取:

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

我在这里使用EF5代码首先,但与POCO非常相似。


Im wanting to use Entity Framework POCO in a disconnected (from context) mode. 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.
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...

  • the objects can be disconnected from the context. (i.e. 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. 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

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

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).

Approach 1 - Setting Entity State

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

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

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:

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

I am using here EF5 Code First, but it is very similar to POCO.

这篇关于实体框架:将现有的POCO添加到新的父POCO中,在DB中创建新的子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆