Sql 实体框架:更新实体或添加实体(如果没有';不存在

Sql 实体框架:更新实体或添加实体(如果没有';不存在,sql,optimization,entity-framework-4,sql-update,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; } enti

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

我想为此执行一个方法(如果只需要一次服务器访问就好了)

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();
但我想避免第一个问题,类似这样的问题:

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();
有类似的吗?或者无论发生什么,我都必须执行第一个查询吗


谢谢

不幸的是,不管发生什么,您都必须执行第一个查询


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

我运行了一些快速测试代码,用于使用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//ie新建对象时

要添加新代码的快速脏代码如下:

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

如果您只是试图限制代码以澄清控制器:

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

如果实体键存在,将进行更新,如果实体键不存在,将进行创建。

对于存在此问题的每个表来说,这将是太多的工作。如果这成为一个性能问题,也许我会这么做。看看我关于使用EF执行通用保存的问题:结果是编写了一个通用保存方法(根据需要插入或更新)。事情很快就会变得一团糟,你没有把注意力集中在主要问题上。您的回答假设我知道是否要更新或插入。这个问题的整个想法是我不知道应该发生什么。“我有一个场景,我必须更新一个实体,如果它存在,或者添加一个新的实体,如果它不存在。”——我给你的示例处理了这个问题,但我做的假设是,entityId对于新添加的实体将为0,对于现有的实体将>0。这对GUID.Yep之类的东西不起作用,但在我的例子中,我添加的元素有一个外键作为组合主键,因此它永远不会为零。如果我有零,我可以用它来代替我的代码的第一个查询。顺便说一句:我再次测试了其他东西,我为两个场景(即编辑和添加)添加了System.Data.EntityState。试试看。