我最近一直在使用Entity Framework 4,并且稍微混淆了何时使用ObjectSet.Attach和ObjectSet.AddObject.
根据我的理解:
所以,如果我正在创建一个新人,我会这样做.
var ctx = new MyEntities();
var newPerson = new Person { Name = "Joe Bloggs" };
ctx.Persons.AddObject(newPerson);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
如果我正在修改现有的人,我这样做:
var ctx = new MyEntities();
var existingPerson = ctx.Persons.SingleOrDefault(p => p.Name = "Joe Bloggs" };
existingPerson.Name = "Joe Briggs";
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
请记住,这是一个非常简单的例子.实际上我使用的是Pure POCO(无代码生成),Repository模式(不处理ctx.Persons)和Unit of Work(不处理ctx.SaveChanges).但是"在幕后",以上是我的实施中发生的事情.
现在,我的问题 - 我还没有找到一个我不得不使用Attach的场景.
我在这里失踪了什么?我们什么时候需要使用Attach?
编辑
只是为了澄清,我正在寻找何时使用Attach over AddObject(或反之亦然)的示例.
编辑2
下面的答案是正确的(我接受了),但我认为我会添加另一个例子,其中Attach将是有用的.
在我上面修改现有Person的示例中,实际上正在执行两个查询.
一个用于检索Person(.SingleOrDefault),另一个用于执行UPDATE(.SaveChanges).
如果(出于某种原因),我已经知道系统中存在"Joe Bloggs",为什么还需要额外的查询才能获得他的第一个?我能做到这一点: …
我试图弄清楚如何将已分离实体的特定属性标记为已修改.如果我执行以下操作,它将标记所有已修改的属性,并且生成的sql将更新所有列.
/// <summary>
/// Sets the entity in the modified state.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity">The entity.</param>
void IDbContext.Modified<T>(T entity)
{
DbEntityEntry<T> entry = Entry(entity);
if (entry.State == EntityState.Modified)
{
// if the state is already Modified we don't need to do anything else
return;
}
if (entry.State == EntityState.Detached)
{
Set<T>().Attach(entity);
//TODO: set specific properties modified instead of the the whole object.
entry.State = EntityState.Modified;
}
}
Run Code Online (Sandbox Code Playgroud)
如何仅将已更改的属性设置为已修改?
我试图在一个实现DbContext将由通用存储库使用的类中使用它.目标是自动确定哪些属性与数据库值相比已更改,然后将这些已更改的属性状态设置为"已修改".在我当前的实现中,Modified方法不知道实体类型,所以我不能简单地用它来检索它context.Set<T>.Find(key).
我想我可以添加一个接受originalEntity参数的重载,但是如果可能的话我宁愿不这样做. …