Ошибка транспортного уровня при получении результатов с сервера Ошибка C # - PullRequest
0 голосов
/ 28 октября 2019

Я пытался прочитать информацию из файла Excel и сохранить ее в SQL.

Когда я запускаю код локально, он работает отлично, но исключение выдается только в среде test .

Ошибка:

Произошла ошибка транспортного уровня при получении результатов с сервера. (провайдер: Session Provider, ошибка: 19 - физическое соединение не используется)

Мой код выглядит следующим образом:

public bool ExtractExcelToDB(int activityId, string tableName, string fileName)
{
    try
    {
        var path = GetPath(activityId);
        path = Path.Combine(path, fileName);

        using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream))
            {
                DataSet result = excelReader.AsDataSet();
                DataTable dt = result.Tables["sheet"];
                DataTable newDt = dt.Select().Skip(1).Take(dt.Rows.Count).CopyToDataTable();

                using (SqlBulkCopy sqlBulk = new SqlBulkCopy(GetConnectionString()))
                {
                    sqlBulk.DestinationTableName = tableName;
                    sqlBulk.WriteToServer(newDt);
                }
            }

            return true;
        }
    }
}

Я записываю исключение в БД, и код не удалсяв этой строке:

sqlBulk.WriteToServer(newDt);

Моя строка подключения на сервере выглядит следующим образом:

<connectionStrings>
    <add name="xxx" 
         connectionString="metadata=res://*/DataModel.csdl|res://*/DataModel.ssdl|res://*/DataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=xxx;initial catalog=xxx;persist security info=True;user id=xxx;password=xxx;multipleactiveresultsets=True;application name=EntityFramework&quot;" 
         providerName="System.Data.EntityClient" />
</connectionStrings>

Я испробовал практически все решения, которые видел без успеха.

РЕДАКТИРОВАТЬ

Я могу сохранить файл с 50 строками, но не с 2000 .. (проблема только в тестовой среде, а не в локальной)

Ответы [ 3 ]

1 голос
/ 28 октября 2019

Текущая строка подключения - Entity Framework строка подключения - используется довольно старый, более не поддерживаемый подход, основанный на использовании базы данных, с моделью базы данных .edmx.

Для SqlBulkCopy, вам нужна clean , необработанная строка подключения ADO.NET - попробуйте что-то вроде этого:

<connectionStrings>
    <add name="BulkCopy" 
         connectionString="data source=xxx;initial catalog=xxx;persist security info=True;user id=xxx;password=xxx;multipleactiveresultsets=True;application name=EntityFramework" 
         providerName="System.Data.SqlClient" />
</connectionStrings>

Используйте эту строку подключения для SqlBulkCopy (адаптируйте GetConnectionStringметод для возврата этой «чистой» строки подключения ADO.NET для компонента массового копирования),

0 голосов
/ 30 октября 2019

Через 2 дня я основал эту работу для себя (также используя @marc_s answer)

Я использую транзакцию и "сохраняю" каждый раз только 10 строк

Вот мой код:

public bool ExtractExcelToDB(int activityId, string tableName, string fileName) {
  using(SqlConnection connection = new SqlConnection(GetConnectionStringBulk())) {
    SqlTransaction tran = null;
    try {
      connection.Open();
      tran = connection.BeginTransaction();

      var path = GetPath(activityId);
      path = Path.Combine(path, fileName);
      using(FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read)) {
        using(IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream)) {
          DataSet result = excelReader.AsDataSet();
          DataTable dt = result.Tables["sheet"];
          DataTable newDt = dt.Select().Skip(1).Take(dt.Rows.Count).CopyToDataTable();
          using(SqlBulkCopy sqlBulk = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, tran)) {
            sqlBulk.DestinationTableName = tableName;

            var bacth = newDt.Rows.Count / 10;
            for (int i = 0; i <= bacth; i++) {
              var rows = newDt.Select().Skip(i * 10).Take(10).ToArray();
              sqlBulk.WriteToServer(rows);
            }
          }

          tran.Commit();

        }
        return true;
      }


    } catch (Exception ex) {


      db.ExceptionErrors.Add(new ExceptionError {
        Value = ex.Message,
          Date = DateTime.Now
      });
      db.SaveChanges();

      if (tran != null) {
        tran.Rollback();
      }

      return false;
    }
  }
}
0 голосов
/ 28 октября 2019
...