实体框架:更新实体或添加(如果它不存在)

时间:2011-06-22 02:56:39

标签: sql optimization entity-framework-4 sql-update

我有一个场景,我必须更新实体(如果它存在)或添加新实体(如果不存在)。

我想为此执行一个单独的方法(如果只是一次访问服务器就会很棒。)

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();

有类似的东西吗?或者我必须执行第一个查询,无论如何?

由于

3 个答案:

答案 0 :(得分:2)

不幸的是,无论如何都必须执行第一个查询。

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

答案 1 :(得分:0)

我使用EF 4在MVC 3中为编辑运行了一些快速测试代码,它似乎可以使用以下代码进行编辑:

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 //即新对象时。

添加新内容的快速和脏代码是:

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");
}

答案 2 :(得分:0)

如果您只是想限制代码以澄清您的控制器:

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

如果实体密钥存在则会更新,如果不存在则会创建。