0

我想使用 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 不在基地) | 名字:约翰 | 姓氏:笼子
  • ID:1 (ID 在基数中) | 名字:梅 | 姓氏:蓝色
  • ID:25 (ID 不在基数中) | 名字:尼克 | 姓氏:西里

并且在数据库中已经记录了ID = 1. 所以第一和第三应该保存,但第二不应该。问题是只有第一条记录在保存,其余的(第二条和第三条)会出错。我不知道为什么?也许是因为这是一笔交易还是什么?有点奇怪。谁能告诉我该怎么做才能保存第一和第三条记录?在这种情况下不仅是第一名吗?


错误:

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

在第三张记录中没有任何意义...

4

3 回答 3

0

您可能会发现自己处于违反 PK 之外的其他约束的情况。这有可能大大增加在添加/更新之前验证所有数据的工作量。对于这些您不能简单地检查记录是否已经存在的场景,我发现一旦发生这样的错误,EF 核心会继续抛出错误,因为它将实体状态保持为“已修改”。

特别是在你的情况下,试试这个:

        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;
        }
于 2022-02-18T12:43:07.850 回答
0

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

  bool exists = db.DB_USER.Where(u => u.ID == newRecord.ID).Any();

    if(!exists)
    {
        //Do the insert
    }
于 2016-06-19T06:58:18.287 回答
-1

您根本不应该在代码中设置 ID。在数据库中,将 ID 设置为 autoincrement .. 当然仍然有它在你的模型中,但不在你的逻辑中

这样,您无需考虑处理 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 并运行代码后,您现在可能也有一个 ID 为 25 的条目,并且再次遇到相同的错误。

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

我还将它移动到 try-catch 块中:

db.DB_USER.Add(newUser);
于 2016-06-18T20:31:35.647 回答