我想使用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);