0

我读取了一个 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

我使用实体框架来执行这个和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文件或比较它们?

我全是耳朵。

4

3 回答 3

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
}
于 2018-11-13T21:52:16.127 回答
0

如果“a”是表上的 PK 并且跨行是唯一的,那么我会在插入之前按 ID 检查现有行的存在。与迈克的回应类似,虽然一个考虑是如果表有许多列,我会避免返回实体,而只是使用存在的检查.Any()

if (!context.Data.Any(x => x.a == row.a)
  // insert the row as a new entity

这里需要注意的是,如果 excel 文件包含编辑、数据更改的现有行,这将不适应。

对于批量导入过程,我通常会首先将 excel 数据暂存到暂存表中来处理这些问题。(在每次导入之前清除暂存表)从那里我会将实体映射到暂存表,而将实体映射到“真实”表。如果可以从文件中提取每条记录的“修改日期”,那么我还将导入日期/时间存储为应用程序的一部分,以便在从临时表中选择要导入的行时,只得到记录修改日期/时间 > 上次导入日期/时间。从那里您可以批量查询临时表中的数据,并查找新记录与现有修改。我发现查询迁移双方的实体比处理导入的内存块更灵活。

于 2018-11-14T00:05:15.003 回答
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();
                            }
                        }
                    }
于 2018-11-14T03:35:30.117 回答