我是EF的新手,我试图了解处理插入和更新数据的最佳方法。仅仅为了某些背景,我使用.net mvc网站锅炉板,我创建了一个与aspnetusers有1:1关系的客户表。我创建了一个管理客户数据的视图。
这是我的HttpPost ActionResult:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AddCard(External.Stripe.Customer customer)
{
if (!ModelState.IsValid)
{
return View(customer);
}
External.Stripe.CustomerOperations co = new External.Stripe.CustomerOperations();
customer = co.Create(customer);
var user = UserManager.FindById(User.Identity.GetUserId());
customer.UserId = user.Id;
var context = new External.Stripe.CustomerContext();
context.Customers.Add(customer);
context.SaveChanges();
return RedirectToAction("Index", "Manage");
}
我觉得我走错了路,因为如果我对客户模型进行任何更新,我实际上需要检查EF,如果我的密钥已经存在,如果存在,则运行更新。我认为如果需要更新,EF会有一种保存模型的本地方式。我也不知道这是否是我坚持我的模型的地方,或者它是否更好地放在我的代码中的其他地方。
答案 0 :(得分:3)
...如果我对客户模型进行任何更新,我实际上需要检查EF,如果我的密钥已经存在,如果确实存在,请改为运行更新。
AddOrUpdate()
就是这样做的。来自文档:
调用SaveChanges时按键添加或更新实体。相当于数据库术语的“upsert”操作
换句话说,将代码更改为:
function foo(callback) {
$.ajax({
url: '...',
success: function(response) {
callback(response) // <-- call it here
}
});
}
foo(function(data){
// use your data here
});
在上面的示例中,context.Customers.AddOrUpdate(c => c.UserId, customer);
context.SaveChanges();
是一个表达式,指定在确定是否应执行“添加”或“更新”操作时应使用c => c.UserId
。
UserId
根据用户提供的任意键值匹配数据库表。在示例中,此键为AddOrUpdate()
。一定要使用合适的钥匙。 UserId
更新所有实体值,并为缺少值的属性将数据库单元格设置为null。在使用之前,请务必设置对象的所有属性值(例如AddOrUpdate()
)。Update Row if it Exists Else Insert Logic with Entity Framework有几个答案可以讨论四种或更多种不同的方法。
答案 1 :(得分:2)
我个人喜欢拉长数据对象并使用if null确定是否应该添加或更新的冗长方法。但是,由于新的或已弃用的业务规则,我确实有一个包含大量列的表,这些列经常被更改。所以我使用下面的
var currentModel = dbContext.Table.First(t => t.Id == _id);
dbContext.Entry(currentModel).CurrentValues.SetValues(newModel);
dbContext.SaveChanges();
我从viewModel获取了我的newModel,其中我有一个返回DTO的ToModel方法。现在我需要更新的是当我对数据库表进行更改时的视图和viewModel。