更新记录(如果存在)

时间:2015-05-13 20:42:01

标签: c# asp.net asp.net-mvc entity-framework

我是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会有一种保存模型的本地方式。我也不知道这是否是我坚持我的模型的地方,或者它是否更好地放在我的代码中的其他地方。

2 个答案:

答案 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。