.db。循环中的 SaveChanges() 在出错后不会保存记录



我想使用epplus从Excel导入数据库。从这里我拿了代码:https://www.paragon-inc.com/resources/blogs-posts/easy_excel_interaction_pt6

using (var db = new DbEntities())
{
    for (var row = 2; row <= lastRow; row++)
    {
        var newRecord = new DB_USER
        {
            ID = Int32.Parse(worksheet.Cells[idColumn + row].Value.ToString()),
            FIRST_NAME = worksheet.Cells[firstNameColumn + row].Value.ToString(),
            LAST_NAME = worksheet.Cells[lastNameColumn + row].Value.ToString(),                               
        };
        db.DB_USER.Add(newRecord);
        try
        {
            db.SaveChanges();
            totalImported++;
        }
        catch (Exception ex)
        {
            resultMessages.Add(string.Format("Error in line #{0}: {1}n", row,
                ex.Message));
        }
    }
}

如果Excel中的数据正确,一切正常。问题是任何记录是否具有无效的数据。例如,我们在Excel中有3个记录:

  • ID:21 (ID不在基础中) |名字:约翰|姓氏:Cage
  • ID:1 (ID在基础中) |名字:梅|姓氏:蓝色
  • ID:25 (ID不在基础中) |名字:尼克|姓氏:Siri

和数据库中的ID = 1已记录。因此,第一和第三应该保存,但第二个应该不保存。问题是只有第一记录是保存,其余的(第二和第三)将出现错误。我不知道为什么?也许是因为这是一笔交易还是什么?有点奇怪。谁能告诉我我该怎么做才能保存第一和第三唱片?不仅在这种情况下是第一个?


错误:

ora-00001:违反唯一约束主键

在第三唱片中没有任何意义...

为什么不在数据库中进行检查,以查看数据库中是否有具有特定ID的用户,并且仅在用户不存在的情况下进行插入:

  bool exists = db.DB_USER.Where(u => u.ID == newRecord.ID).Any();
    if(!exists)
    {
        //Do the insert
    }

您可能会发现自己处于违反PK以外的其他约束的情况下。这有可能大大增加在添加/更新之前有效所有数据的努力。对于这些情况,您无法简单地检查记录是否已经存在,我发现一旦发生这样的错误,EF Core将继续丢弃错误,因为它将实体状态保持为"修改"。

特别是在您的情况下,请尝试以下操作:

        try
        {
            db.SaveChanges();
            totalImported++;
        }
        catch (Exception ex)
        {
            resultMessages.Add(string.Format("Error in line #{0}: {1}n", row,
                ex.Message));
            db.Entry(db.DB_USER).State = EntityState.Unchanged;
        }

您根本不应该在代码中设置ID。在数据库中,将ID设置为自动启动。。

这样,您将不需要考虑处理ID,而是要让实体框架处理

无论如何,以下是如何更改代码的想法:

        using (var db = new DbEntities())
            {
                foreach (user in db)
                {
                    var userExists = db.DB_USER.Where(u => u.ID == user.ID);
                    if(!userExists)
                    {
                        var newUser = new DB_USER
                        {
                                ID = Int32.Parse(worksheet.Cells[idColumn + row].Value.ToString()),
                                FIRST_NAME = worksheet.Cells[firstNameColumn + row].Value.ToString(),
                                LAST_NAME = worksheet.Cells[lastNameColumn + row].Value.ToString(),                               
                        };
                        try
                        {
                            db.DB_USER.Add(newUser);
                            db.SaveChanges();
                            totalImported++;
                        }
                        catch (Exception ex)
                        {
                             resultMessages.Add(string.Format("Error in line #{0}: {1}n", row,
                             ex.Message));
                        }
                    }
                }
            }

我的猜测仍然是,由于您的问题中的代码是在第三行开始的(这似乎是ID 21在您更改它之前,它可能会导致您认为这是第一行工作正常。

如果刷新数据库,则可能已经有ID 21的数据库中的条目它到25,然后运行您现在可能有25的代码,并且又有相同的错误。

我在代码中添加了一个foreach循环,并检查了条目的存在,因此代码应避免主关键违规。

我还将其移入try-catch块中:

db.DB_USER.Add(newUser);

最新更新