我读取了一个Excel文件并将该数据插入数据库表中,但是每次执行此操作时,它都会添加现有行以及新数据,我只想插入表中尚未存在的行,我唯一的ID是当前时间戳。
例如,这是我第一次插入时当前发生的情况:
ExcelFile Database Table
a | b | date a | b | date
----------- ---------------
1 | 1 | 2018/02/12 1 | 1 | 2018/02/12
2 | 2 | 2018 /03/12 2 | 2 | 2018 /03/12
这是在我第二次插入时发生的:
ExcelFile Database Table
a | b | date a | b | date
----------- ---------------
1 | 1 | 2018/02/12 1 | 1 | 2018/02/12
2 | 2 | 2018 /03/12 2 | 2 | 2018 /03/12
3 | 3 | 2018 /04/12 1 | 1 | 2018/02/12
2 | 2 | 2018 /03/12
3 | 3 | 2018 /04/12
我使用Entity Framework来执行此操作,并使用ExcelDataReader
包:
var result = reader.AsDataSet();
DataTable dt = new DataTable();
dt = result.Tables[0]; // here I store the data from the Excel file
foreach (DataRow row in dt.Rows)
{
using (AppContext context = new AppContext())
{
Data data = new Data();
string date = row.ItemArray[4].ToString();
DateTime parseDate = DateTime.Parse(date);
Data datos = new Data
{
a = row.ItemArray[0].ToString(),
b = row.ItemArray[1].ToString(),
c = row.ItemArray[2].ToString(),
d = row.ItemArray[3].ToString(),
e = parseDate
};
context.Data.Add(datos);
context.SaveChanges();
}
}
是否可以过滤excel文件或进行比较?
我全是耳朵。
答案 0 :(得分:0)
在添加之前检查现有行。以下应插入您计算parseDate
的位置。
var existingRow = context.Data.FirstOrDefault(d=>d.e == parseDate); //Note that the ".e" should refer to your "date" field
if (existingRow != null)
{
//This row already exists
}
else
{
//It doesn't exist, go ahead and add it
}
答案 1 :(得分:0)
如果“ a”是表上的PK,并且在行之间是唯一的,那么在插入之前,我将通过ID检查现有行的存在。与Mike的响应类似,尽管一个考虑因素是表是否具有许多列,我会避免返回该实体,而只是使用.Any()
if (!context.Data.Any(x => x.a == row.a)
// insert the row as a new entity
此处需要说明的是,如果excel文件中包含编辑内容,而现有行中的数据发生了更改,则这将无法容纳。
对于批量导入过程,我通常会先通过将excel数据首先登台到登台表中来进行处理。 (在每次导入之前清除登台表)从那里,我将有实体映射到登台表,而实体则映射到“真实”表。如果存在可以从文件中为每个记录提取的“修改日期”,那么我还将存储导入日期/时间作为应用程序的一部分,以便在选择要从登台表中导入的行时,仅获取记录修改日期/时间>上次导入日期/时间的位置。从那里,您可以批量查询暂存表中的数据,并查找新记录与现有修改。我发现迁移双方的查询实体都比处理导入中的内存块更灵活。对于小的导入来说,这可能不值得,但是对于较大的文件(您希望使用较小的子集和过滤),可以使事情变得更容易。
答案 2 :(得分:0)
在@MikeH的帮助下,我可以完全执行所需的操作 这样,仅添加了具有不同DateTime的行(在我的情况下,DateTime始终是升序值。)
foreach (DataRow row in dt.Rows) // dt = my dataTable loaded with ExcelDataReader
{
using (AppContext context = new AppContext())
{
string date = row.ItemArray[4].ToString();
DateTime parseDate = DateTime.Parse(date); // I did a parse because the column "e" only accepted DateTime and not String types.
var existingRow = context.Data.FirstOrDefault(d => d.e == parseDate);
if (existingRow != null)
{
Console.WriteLine("Do Nothing");
}
else
{
Data datos = new Data
{
a = row.ItemArray[0].ToString(),
b = row.ItemArray[1].ToString(),
c = row.ItemArray[2].ToString(),
d = row.ItemArray[3].ToString(),
e = parseDate
};
context.Data.Add(datos);
context.SaveChanges();
}
}
}