【问题标题】:Update record if it exists更新记录(如果存在)
【发布时间】:2015-07-25 07:56:35
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

简答

...如果我对客户模型进行任何更新,我实际上需要检查 EF 是否我的密钥已经存在,如果存在,则改为运行更新。

AddOrUpdate() 就是这样做的。来自文档:

在调用 SaveChanges 时按键添加或更新实体。相当于数据库术语中的“更新插入”操作

示例

换句话说,将您的代码更改为:

context.Customers.AddOrUpdate(c => c.UserId, customer);
context.SaveChanges();

在上面的示例中,c =&gt; c.UserId 是一个表达式,指定在确定是否应执行添加或更新操作时应使用UserId

注意事项

  • AddOrUpdate() 基于用户提供的任意键值匹配数据库表。在示例中,此密钥为UserId。请务必使用适当的密钥。
  • AddOrUpdate() 更新所有 实体值并将缺少值的属性的数据库单元格设置为空。请务必在使用前设置对象的所有属性值(例如customer)。

另见

Update Row if it Exists Else Insert Logic with Entity Framework 它有几个答案,讨论了四种或更多不同的方法。

【讨论】:

  • AddOrUpdate 不是用于迁移吗?
  • 它看起来确实主要是为迁移而设计的,但它的工作方式完全符合预期。我的另一个问题是我什至需要写这种东西,还是有更好的方法来做我想做的事情?使用简单的 CRUD 操作,这似乎是很多额外的开销。
  • 必读:注意AddOrUpdate方法:thedatafarm.com/data-access/…
【解决方案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。

【讨论】:

  • 使用dbContext.Table.First(t =&gt; t.Id == _id) 来检查是否存在与我们使用AddOrUpdate 检查是否存在的方式有相同的限制。在这两种情况下,都由用户提供适当的键值。在您的示例中,您碰巧正在检查 Id 值,这可能是一个主键。那挺好的。但是对于不太了解情况的用户使用不适当的密钥仍然可能
猜你喜欢
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-02
相关资源
最近更新 更多