从服务器错误 C# 接收结果时发生传输级错误
A transport-level error has occurred when receiving results from the server Error C#
我试图从 excel 文件中读取信息并将其保存在 SQL 中。
当我 运行 本地代码时,它运行完美,但仅在 test 环境中抛出异常。
错误是:
A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
我的代码如下所示:
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="data source=xxx;initial catalog=xxx;persist security info=True;user id=xxx;password=xxx;multipleactiveresultsets=True;application name=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
我几乎尝试了所有看到的解决方案,但都没有成功。
编辑
I can save file with 50 rows but not with 2000.. (Problem only in test
environment not in local)
您当前的连接字符串是 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
方法调整为 return 此 "pure" ADO.NET 批量复制组件的连接字符串) ,
你应该从 msdn 看到这个页面...
2 天后我为我创建了这项工作(也使用@marc_s 回答)
我使用事务并且"save"每次只有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;
}
}
}
我试图从 excel 文件中读取信息并将其保存在 SQL 中。
当我 运行 本地代码时,它运行完美,但仅在 test 环境中抛出异常。
错误是:
A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
我的代码如下所示:
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="data source=xxx;initial catalog=xxx;persist security info=True;user id=xxx;password=xxx;multipleactiveresultsets=True;application name=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
我几乎尝试了所有看到的解决方案,但都没有成功。
编辑
I can save file with 50 rows but not with 2000.. (Problem only in test environment not in local)
您当前的连接字符串是 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
方法调整为 return 此 "pure" ADO.NET 批量复制组件的连接字符串) ,
你应该从 msdn 看到这个页面...
2 天后我为我创建了这项工作(也使用@marc_s 回答)
我使用事务并且"save"每次只有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;
}
}
}