我最近一直在使用Entity Framework 4,对于何时使用ObjectSet.Attach和ObjectSet.AddObject感到有些困惑。
据我了解:
因此,如果我要 创建一个新的Person ,则可以执行此操作。
var ctx = new MyEntities(); var newPerson = new Person { Name = "Joe Bloggs" }; ctx.Persons.AddObject(newPerson); ctx.SaveChanges();
如果我要 修改现有的Person ,请执行以下操作:
var ctx = new MyEntities(); var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" }; existingPerson.Name = "Joe Briggs"; ctx.SaveChanges();
请记住,这是一个 非常简单的 示例。实际上,我使用的是Pure POCO(不生成代码),存储库模式(不处理ctx.Persons)和工作单元(不处理ctx.SaveChanges)。但是,“在幕后”,以上就是我的实现过程。
现在,我的问题 -我还没有找到必须使用 Attach的情况 。
我在这里想念什么?我们什么时候需要使用Attach?
编辑
只是为了澄清,我正在寻找何时使用AddObject上的Attach的 示例 (反之亦然)。
编辑2
下面的答案是正确的(我接受了),但以为我会添加另一个示例,其中“附加”将很有用。
在我上面的用于 修改现有Person的 示例中,实际上正在执行两个查询。
一个用于检索Person(.SingleOrDefault),另一个用于执行UPDATE(.SaveChanges)。
如果(由于某种原因)我已经知道系统中存在“ Joe Bloggs”,为什么还要进行额外的查询才能首先找到他?我可以这样做:
var ctx = new MyEntities(); var existingPerson = new Person { Name = "Joe Bloggs" }; ctx.Persons.Attach(existingPerson); ctx.SaveChanges();
这将导致仅执行UPDATE语句。
ObjectContext.AddObject 和 ObjectSet.AddObject : 该 ADDOBJECT 方法是将那些新创建的对象 不 存在于数据库中。该实体将获得自动生成的临时 EntityKey ,其EntityState将设置为 Added 。调用SaveChanges时,对于EF来说很清楚,该实体需要插入数据库中。
ObjectContext.Attach 和 ObjectSet.Attach : 另一方面, Attach 用于数据库中已经 存在的 实体。Attach不会将EntityState设置为Added,而是会产生 Unchanged EntityState,这意味着自从将它附加到上下文以来,它没有发生变化。假定要附加的对象存在于数据库中。如果在对象附加后对其进行修改,则在调用SaveChanges时,EntityKey的值将用于通过在db表中找到其匹配ID来更新(或删除)相应的行。
此外,使用Attach方法,可以定义ObjectContext中已经存在但具有 没有 自动连接。基本上,Attach的主要目的是连接已附加到ObjectContext且 不是 新实体,因此您不能使用Attach附加已添加EntityState的实体。在这种情况下,您必须使用 Add() 。
例如,假设您的Person实体具有一个名为 Addresses 的导航属性,它是 Address 实体的集合。假设您已经从上下文中读取了两个对象,但是它们彼此之间不相关,并且您想要这样做:
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" }; var myAddress = ctx.Addresses.First(a => a.PersonID != existingPerson.PersonID); existingPerson.Addresses.Attach(myAddress); // OR: myAddress.PersonReference.Attach(existingPerson) ctx.SaveChanges();