实体框架:更新实体,如果不存在则添加
Posted
技术标签:
【中文标题】实体框架:更新实体,如果不存在则添加【英文标题】:Entity Framework: Update entity or add if it doesn't exist 【发布时间】:2011-06-22 02:56:38 【问题描述】:我有一个场景,如果实体存在,我必须更新它,如果不存在,我必须添加一个新实体。
我想为此执行一个方法(如果它是一次到服务器的旅行会很棒)。
在 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();
有没有类似的?还是无论如何我都必须执行第一个查询?
谢谢
【问题讨论】:
看看我关于使用 EF 进行通用保存的问题:***.com/questions/6018711/… 其结果是编写通用保存方法(根据需要插入或更新)。它很快就会变得一团糟。 【参考方案1】:不幸的是,无论如何,您都必须执行第一个查询。
一种选择是编写一个执行 T-SQL MERGE
的存储过程,然后将其映射到函数导入,尽管这需要您将实体的标量值作为参数传递(并支持导航属性会完成),但它会完成你所追求的。
【讨论】:
对于我遇到此问题的每个表来说,这将是太多的工作。如果这成为性能问题,也许我会这样做。【参考方案2】:我在带有 EF 4 的 MVC 3 中为 editing 运行了一些快速测试代码,它似乎可以使用以下代码进行编辑:
using (var context = new Test***Entities())
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 Test***Entities())
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");
【讨论】:
您没有专注于主要问题。您的回复假定我知道是否要更新或插入。这个问题的整个想法是我不知道应该发生什么。 “我有一个场景,如果实体存在,我必须更新它,如果不存在,我必须添加一个新实体。” -- 我给你的样本处理了这个问题,但我假设 entityId 为 0 表示新添加的,> 0 表示现有的。这不适用于 GUID。 是的,但在我的情况下,我添加的元素有一个外键作为组合主键,因此它永远不会为零。如果我有零,我可以使用它而不是我的代码的第一个查询。 顺便说一句:我再次测试了其他东西,我有 System.Data.EntityState.Added 用于两种场景(即编辑和添加),它似乎工作正常。试试看。【参考方案3】:如果您只是想限制代码以阐明您的控制器:
db.Attach(model);
db.SaveChanges(model);
如果实体键存在则更新,如果不存在则创建。
【讨论】:
以上是关于实体框架:更新实体,如果不存在则添加的主要内容,如果未能解决你的问题,请参考以下文章
添加 Mysql 实体框架时,Visual Studio 中的表“dbname.dbname.tablename”不存在错误
Symfony 3.4 - 如果在多对多关系上不存在,则持续存在