2011-06-22 37 views
5

我有一个场景,我必须更新实体,如果它存在或添加一个新的,如果它不。实体框架:更新实体或添加,如果它不存在

我想为此执行一个单一的方法(如果它是单次访问服务器,那将会很棒)。

在EF中是否有类似的东西?

现在我的代码如下所示:

var entity = db.Entities.FirstOrDefault(e => e.Id == myId); 
if (entity == null) 
{ 
    entity = db.Entities.CreateObject(); 
    entity.Id = myId; 
} 

entity.Value = "my modified value"; 

db.SaveChanges(); 

但我想避免的第一个查询,像这样:

var entity = new Entity(); 
entity.Id = myId; 
entity.Value = "my modified value"; 
db.AddOrAttach(entity); 
db.SaveChanges(); 

有什么相似?还是必须执行第一个查询?

谢谢

+0

我的问题来看看这样做一般的保存与EF:http://stackoverflow.com/questions/6018711/generic-way-to-check-if-entity-exists-in-entity-framework的结果这是(根据需要插入或更新)写一个通用的保存方法。它很快变得混乱。 – Yuck

回答

2

不幸的是,您必须执行第一个查询。

一个选择是编写一个执行T-SQL的存储过程MERGE然后将其映射到一个函数导入,但这需要您将该实体的标量值作为参数传递(并支持导航属性完成),但它会完成你以后的事情。

+0

对于每个有此问题的表格,这都会造成太大的影响。如果这成为性能问题,也许我会这样做。 – willvv

0

我跑了编辑一些快速的测试代码在MVC 3与EF 4,它似乎为编辑与下面的代码工作:

using (var context = new TestStackOverFlowEntities()) 
{ 
    Person p = new Person(); 
    p.Id = long.Parse(collection["Id"]); 
    p.FirstName = collection["FirstName"]; 
    p.LastName = collection["LastName"]; 
    context.People.Attach(p); 
    context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Modified); 
    context.SaveChanges(); 
    return RedirectToAction("Index"); 
} 

编辑:我有太多创建新的对象被选中,您需要改变这个

context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Added); 

当Id == 0 // ie ie new object。

快速和肮脏的代码添加新是这样的:

using (var context = new TestStackOverFlowEntities()) 
{ 
    Person p = new Person();       
    p.Id = 0; 
    p.FirstName = collection["FirstName"]; 
    p.LastName = collection["LastName"]; 
    context.People.Attach(p); 
    context.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Added); 
    context.SaveChanges(); 
    return RedirectToAction("Index"); 
} 
+1

你不关注主要问题。您的回复假定我知道是否要更新或插入。这个问题的整个想法是,我不知道会发生什么。 – willvv

+0

“我有一种情况,我如果存在或添加一个新的,如果它不更新的实体。” - 我给你的样本可以处理这个问题,但是我做的假设是entityId对于新添加的将为0,对于现有的对象为> 0。这不适用于像GUID的东西。 –

+1

是的,但对我来说,我添加元素有一个外键的组合主键,因此它永远不会是零。如果我有零,我可以使用它而不是我的代码的第一个查询。 – willvv

0

如果你只是试图限制代码澄清你的控制器:

db.Attach(model); 
db.SaveChanges(model); 

将更新,如果实体键存在,如果没有创建。

+0

当然还有两个疑问。 – shannon