asp.net-mvc 更新数据库条目 MVC 实体框架

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25752086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:14:00  来源:igfitidea点击:

Updating database entry MVC Entity Framework

asp.net-mvcentity-framework

提问by Pierre

I have a Payment model with a 'Status' boolean value which defaults to false. Once payment has been made, I need to update that specific payment's 'Status' to true.

我有一个带有默认为 false 的“状态”布尔值的付款模型。付款后,我需要将该特定付款的“状态”更新为 true。

Here's the code I've been trying to use to change the specific database entry, but it's just not changing it. What am I doing wrong?

这是我一直试图用来更改特定数据库条目的代码,但它并没有改变它。我究竟做错了什么?

Payment payment = new Payment();
payment = db.Payments.Find(orderId);
db.Entry(payment).State = EntityState.Modified;
payment.Status = true;
db.SaveChanges();

Thanks!

谢谢!

This is what ended up working:

这就是最终的工作:

using (var con = new ApplicationDbContext())
{
    payment = con.Payments.First(x => x.Id == orderId);
    payment.Status = true;

    con.Payments.Attach(payment);
    var entry = con.Entry(payment);
    entry.Property(e => e.Status).IsModified = true;
    con.SaveChanges();
}

回答by ali golshani

Payment payment = new Payment();
payment = db.Payments.Find(orderId);
payment.Status = true;
db.Entry(payment).State = EntityState.Modified;
db.SaveChanges();

回答by Radu Porumb

The reason all of these are failing is because either the Payment object is never attached to the DBContext or the orderId doesn't actually match up with the PK on the Payments table. In order for SaveChanges()to actually work, the object you're changing needs to be tracked by the DBContext, not just have its EntityStateset to Modified. Also all these examples seem grossly overcomplicated.

所有这些都失败的原因是因为 Payment 对象从未附加到 DBContext 或 orderId 实际上与 Payments 表上的 PK 不匹配。为了SaveChanges()实际工作,您正在更改的对象需要由 DBContext 跟踪,而不仅仅是将其EntityState设置为Modified. 此外,所有这些例子似乎都过于复杂。

using (var db = new DbContext())
{
    // make sure you have the right column/variable used here
    var payment = db.Payments.FirstOrDefault(x => x.Id == orderId);

    if(payment == null) throw new Exception("Invalid id: " + orderId);

    // this variable is tracked by the db context
    payment.Status = true;

    db.SaveChanges();
}

回答by Alex Art.

Try this one:

试试这个:

    Payment payment;
    using (var context = new DBContext()) //replace the name of your context
    {
        payment = context.Payments.Find(orderId);
    }

    if(payment != null)
    {
       payment.Status = true;
    }

    using (var context = new DBContext()) //replace the name of your context
    {
        context.Payments.Attach(payment);
        context.Entry(payment).State = System.Data.EntityState.Modified;    
        context.SaveChanges();
    }

回答by aleha

As mentioned here:

正如这里提到的:

The Find method on DbSet uses the primary key value to attempt to find an entity tracked by the context. If the entity is not found in the context then a query will be sent to the database to find the entity there. Null is returned if the entity is not found in the context or in the database.

DbSet 上的 Find 方法使用主键值来尝试查找由上下文跟踪的实体。如果在上下文中未找到实体,则将向数据库发送查询以在那里找到实体。如果在上下文或数据库中找不到实体,则返回 Null。

So be sure that Payment class looks like this:

因此,请确保 Payment 类如下所示:

public class Payment
{
     [Key]
     public int Id {get; set;}
     public bool Status {get; set;}
}

And your Entry save logic could look like this:

您的条目保存逻辑可能如下所示:

Payment payment = null;
using (var ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0)))
{
    using (var context = new DBContext()) 
    {
        context.Database.Log = s => { System.Diagnostics.Debug.WriteLine(s); };
        payment = context.Payments.Find(orderId);
        if(payment != null)
        {
            payment.Status = true;
            context.Entry(payment).State = System.Data.EntityState.Modified;    
        }
        else 
        {
            context.Payments.Add(new Payment(){
                Status = true
            });
        }
        context.SaveChanges();
    }
    ts.Complete();
}

Added transaction scope to be sure that it is properly open and close, and added sql query logging to debug window.

添加了事务范围以确保它正确打开和关闭,并在调试窗口中添加了 sql 查询日志记录。

回答by PedroSouki

If you just have your entity id, just do like Ali Golshani said. But if you already have the entity and just want to update, you can do this way:

如果你只有你的实体 ID,就像 Ali Golshani 所说的那样。但是如果您已经拥有实体并且只想更新,您可以这样做:

 public void Update(Payment payment, int orderId)
    {
        //first find the entity to update
        Payment oldEntity = DbSet.Find(orderId);

        //detach this entity from the DbSet
        Db.Entry(oldEntity).State = EntityState.Detached;

        //set the state from the entity that you just received to modified 
        Db.Entry(obj).State = EntityState.Modified;
    }

Detaching avoids the error message: "Attaching an entity failed because another entity of the same type already has the same primary key value".

分离避免了错误消息:“附加实体失败,因为相同类型的另一个实体已经具有相同的主键值”。

I hope that it helps.

我希望它有帮助。