问题:我需要在一个多表插入中获得一个标识,并且需要在实体框架.中封装事务支持。
我有两个(psuedo泛型)对象和相应的表,Book和Author:
create table Author
(authorid int identity primary key,
authorname varchar(max)
)
create table Book
(bookid int identity primary key,
bookname varchar(max),
authorid int references Author(authorid)
)我的问题是,当我需要与一个新作者插入一本新书时,我最终需要这样做,如果图书插入抛出一个异常,我有一个作者没有对我的应用程序不利的图书。
context.Authors.Add(newauthor);
context.SaveChanges();
newbook.AuthorID = newauthor.ID //I can read this now because the SaveChanges() created the ID
context.Books.Add(newbook);
context.SaveChanges();我浏览了一下这篇文章,它基本上说不要在EntityFramework中使用事务,并建议每次操作调用SaveChanges()一次,让EF自己处理事务。我很乐意,但我需要首先从表中获得身份,就像我的psuedo代码和这个问题中指出的那样
发布于 2013-11-06 23:10:35
问题是-你绝对需要插入作者的ID吗?
您可以使用实体进行开发,可以先使用代码,也可以使用db优先。如果您首先使用db,您将拥有具有生成实体、导航属性和集合的.edmx文件.因此,对于Author实体来说,由于关系authorid int references Author(authorid)在您的表书中有,上面关键特性的意义是什么。因此,要将书添加到作者,只需制作如下内容:
//Somewhere here author is created, add it to context.Authors
context.Authors.Add(newauthor);
//Somewhere here book is created, don't need to add it to context.Books; don't call SaveChanges either
newauthor.Books.Add(newbook);// And this is all you need; ID management will be done by Entity, automatically
context.SaveChanges(); // Only one call to save changes you will need
//Of course, all IDs of inserted entities will be available here... 类似的结构对于代码优先也是有效的;在Author实体中,您很可能拥有public virtual ICollection<Book> Books集合。书的创作将按照上面所述的方式进行。
当然,您可以使用多个context.SaveChanges()来获取新插入实体的ID --您不应该这样做。每个SaveChanges()只是在服务器的往返广告,很可能,你将以糟糕的性能结束。最好将ID值的管理留给实体,如上文所述。
然后,完成这个故事。有了上面的结构,EF会在事务中自动包装所有向上到-SaveChanges()。因此,如果Book插入失败,Author插入也将被撤消。
发布于 2013-11-06 23:17:07
如果您真的不想在代码中使用事务,那么您可以将所有内容包装在存储过程中。但是,仅仅因为默认的隔离级别是可序列化的,就没有理由不能更改它:
using(var scope = new TransactionScope(
TransactionScopeOption.RequiresNew,
new TransactionOptions() {
IsolationLevel = IsolationLevel.ReadCommitted
})) {
context.Authors.Add(newauthor);
context.SaveChanges();
newbook.AuthorID = newauthor.ID
context.Books.Add(newbook);
context.SaveChanges();
scope.Complete();
}也就是说,按照Dmitriy的回答,你通常不需要手工操作。
https://stackoverflow.com/questions/19824542
复制相似问题