实体框架:将现有子POCO到新的父POCO,创造了新的孩子在DB [英] Entity Framework: adding existing child POCO to new Parent POCO, creates new child in DB
问题描述
林想使用实体框架POCO处于断开(从上下文中)模式。在我的方案,我创建一个新的父对象,并希望现有的子对象附加到它,然后将其保存到数据库。
以下不期望的code保存新的学生记录时插入一个新的球场纪录,如果不是我想现有的球场纪录链接到新的学生记录。
我怎样才能做到这一点在实体框架在那里......
- 的对象可以从上下文断开。 (即查询在一个上下文,然后保存在不同的上下文中)
- 我不需要重新查询从数据库的子记录只是这样我就可以把它连接到父时,我保存到数据库。我真的想避免做多趟分贝时,我已经拥有它在内存中的对象。
该页面显示了code以下是根据<一个数据库图href="http://entityframeworktutorial.net/EF4_EnvSetup.aspx#.UPMZ4m-UN9Y">http://entityframeworktutorial.net/EF4_EnvSetup.aspx#.UPMZ4m-UN9Y
类节目
{
静态无效的主要(字串[] args)
{
//从数据库作为断开连接的对象获得现有课程
变种当然= Program.getCourse();
//创建新的学生
VAR螺柱=新的学生();
stud.StudentName =鲍勃;
//分配现有课程的学生
stud.Courses.Add(当然);
//保存学生分贝
使用(SchoolDBEntities CTX =新SchoolDBEntities())
{
ctx.Students.AddObject(螺栓);
ctx.SaveChanges();
}
}
静电场getCourse()
{
当然returnCourse = NULL;
使用(VAR CTX =新SchoolDBEntities())
{
ctx.ContextOptions.LazyLoadingEnabled = FALSE;
returnCourse =(从S在ctx.Courses
选择S).SingleOrDefault();
}
返回returnCourse;
}
}
我相信有完成这个的几种方法。 您可以指定实体当然是不变的,而不是增加,沿着这些线路:
ctx.Entry(当然).State = EntityState.Unchanged;
或指导你的背景,你正在使用现有的实体:
ctx.Courses.Attach(课程);
这里更多信息: <一href="http://msdn.microsoft.com/en-us/data/jj592676.aspx">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.
这篇关于实体框架:将现有子POCO到新的父POCO,创造了新的孩子在DB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!