繁体   English   中英

使用C#,EF和SQL Server,仅将不存在的行从Excel文件插入数据库

[英]Insert into database from an Excel file only rows that don't exist, using C#, EF, and SQL Server

我读取了一个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文件或进行比较?

我全是耳朵。

在添加之前检查现有行。 下面应插入计算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
}

如果“ a”是表上的PK,并且在行之间是唯一的,那么在插入之前,我将通过ID检查现有行的存在。 与Mike的响应类似,尽管一个考虑因素是表是否具有许多列,我会避免返回该实体,而只是使用.Any()进行存在检查

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

需要注意的是,如果excel文件包含编辑,数据更改的现有行,则不能容纳该行。

对于批量导入过程,我通常会先将excel数据先登台到登台表中,然后再进行处理。 (在每次导入之前清除登台表)从那里,我将有实体映射到登台表,而实体则映射到“真实”表。 如果存在可以从文件中为每个记录提取的“修改日期”,那么我还将存储导入日期/时间作为应用程序的一部分,以便在选择要从登台表中导入的行时,仅获取记录修改日期/时间>上次导入日期/时间的位置。 从那里,您可以批量查询暂存表中的数据,并查找新记录与现有修改。 我发现迁移双方的查询实体都比处理导入中的内存块更灵活。 如果导入量较小,则可能不值得,但是对于较大的文件(您希望使用较小的子集和过滤),这会使事情变得更容易。

我可以在@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();
                            }
                        }
                    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM