我有一个场景,我必须更新实体(如果它存在)或添加新实体(如果不存在)。
我想为此执行一个单独的方法(如果只是一次访问服务器就会很棒。)
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 :(得分: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);
如果实体密钥存在则会更新,如果不存在则会创建。