Вставлять в базу данных из файла Excel только несуществующие строки, используя C #, EF и SQL Server - PullRequest
0 голосов
/ 14 ноября 2018

Я читаю файл Excel и вставляю эти данные в таблицу базы данных, но каждый раз, когда я делаю это, он добавляет существующие строки плюс новые данные, я только хочу вставить строки, которых еще нет в таблице,мой уникальный идентификатор - это текущая отметка времени.

Например, вот что происходит сейчас, когда я делаю первую вставку:

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 или сравнить их?

IУ меня все уши.

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Если «а» является PK в таблице и уникальным для всех строк, то перед вставкой я бы проверил существование существующих строк по идентификатору.Аналогично ответу Майка, хотя одно из соображений заключается в том, что если в таблице есть несколько столбцов, я бы не стал возвращать сущность, а использовал бы только проверку на существование, используя .Any()

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

.файл содержит правки, существующие строки, в которых данные изменяются, это не будет соответствовать этому.

Для процессов массового импорта я обычно подходил бы к ним, сначала помещая данные Excel в промежуточную таблицу.(очистка промежуточной таблицы перед каждым импортом) Оттуда у меня будут сущности, сопоставленные с промежуточными таблицами, против сущностей, сопоставленных с «настоящими» таблицами.Если есть «измененная дата», которая может быть извлечена из файла для каждой записи, тогда я бы также сохранил дату / время импорта как часть приложения, чтобы при выборе строк для импорта из промежуточной таблицы получалось только получитьзаписи, где эта измененная дата / время> последняя дата / время импорта.Оттуда вы можете запрашивать данные из промежуточной таблицы в пакетном режиме и искать новые записи в сравнении с существующими изменениями.Я считаю, что запрос сущностей на обеих сторонах миграции более гибкий, чем работа с блоком в памяти для импорта.При небольшом импорте это может быть бесполезным, но для больших файлов, где вы захотите работать с меньшими подмножествами и фильтрацией, это может упростить задачу.

0 голосов
/ 14 ноября 2018

Я мог выполнить в точности то, что мне было нужно, с помощью @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();
                            }
                        }
                    }
0 голосов
/ 14 ноября 2018

Проверьте существующую строку перед ее добавлением. Ниже должно быть вставлено ниже, где вы рассчитываете 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...