且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

实体框架:将现有子POCO到新的父POCO,创造了新的孩子在DB

更新时间:2023-12-01 17:59:10

我相信有完成这个的几种方法。 您可以指定实体当然是不变的,而不是增加,沿着这些线路:

  ctx.Entry(当然).State = EntityState.Unchanged;
 

或指导你的背景,你正在使用现有的实体:

  ctx.Courses.Attach(课程);
 

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

修改

有从我的解决方案运行一些样品,我验证它们正常工作。 在所有情况下,我们有出版商记录在数据库带有ID = 2和Name =Addison Wesley出版(无关的例子,但只是良好的措施)。

方法1 - 设置实体状态

 使用(VAR上下文=新的上下文())
{
    VAR书=新的图书();
    book.Name =服务设计模式;
    book.Publisher =新发行(){n = 2}; //只有ID是必需的
    context.Entry(book.Publisher).State = EntityState.Unchanged;
    context.Books.Add(书);
    context.SaveChanges();
}
 

方法2 - 使用Attach方法

 使用(VAR上下文=新的上下文())
{
    VAR书=新的图书();
    book.Name =服务设计模式;
    book.Publisher =新发行(){n = 2}; //只有ID是必需的
    context.Publishers.Attach(book.Publisher);
    context.Books.Add(书);
    context.SaveChanges();
}
 

方法3 - 设置外键值

 使用(VAR上下文=新的上下文())
{
     VAR书=新的图书();
     book.Name =服务设计模式;
     book.PublisherId = 2;
     context.Books.Add(书);
     context.SaveChanges();
}
 

对于最后的方法来工作,我需要添加额外的属性PublisherId,它必须根据NavigationPropertyName +ID规则命名被拾起由EF auotmatically:

 公众诠释PublisherId {获得;组; }
公开发行发行{获得;组; }
 

我在这里使用EF5 code第一,但它是非常相似的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.