c# - 使用 Entity Framework 进行多次插入会导致 => 物理连接不可用

标签 c# sql-server entity-framework stored-procedures

我使用最新的 Entity Framework 并通过存储过程插入大约 425000 个实体。

然后发生异常。它仍然插入了 32766 个实体。

代码

using (var context = new MyContext())
{
    foreach (var item in attributes)
    {
        CreateAttribute(item.productXml, item.NewProduct, context);
    }
}

private static void CreateAttribute(XmlProduct xmlProduct, ProductBase newProdB, MyContext context)
{
    foreach (string attribute in xmlProduct.Properties.Keys)
    {
        double doubleValue;
        if (double.TryParse(xmlProduct.Properties[attribute], out doubleValue))
        {
            //if cast fails
            context.app_sp_AddAttribute(attribute, doubleValue, null, newProdB.ID);
        }
        else
        {
            context.app_sp_AddAttribute(attribute, null, xmlProduct.Properties[attribute], newProdB.ID);
        }
    }
}

错误

A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)

我该如何修复该错误?

更新

public virtual ObjectResult<Nullable<int>> app_sp_AddAttribute(string attributeName, Nullable<double> numericValue, string stringValue, Nullable<int> productID)
{
    var attributeNameParameter = attributeName != null ?
        new ObjectParameter("AttributeName", attributeName) :
        new ObjectParameter("AttributeName", typeof(string));

    var numericValueParameter = numericValue.HasValue ?
        new ObjectParameter("NumericValue", numericValue) :
        new ObjectParameter("NumericValue", typeof(double));

    var stringValueParameter = stringValue != null ?
        new ObjectParameter("StringValue", stringValue) :
        new ObjectParameter("StringValue", typeof(string));

    var productIDParameter = productID.HasValue ?
        new ObjectParameter("ProductID", productID) :
        new ObjectParameter("ProductID", typeof(int));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<int>>("app_sp_AddAttribute", attributeNameParameter, numericValueParameter, stringValueParameter, productIDParameter);
}

异常发生在返回语句处!

An unhandled exception of type 'System.Data.Entity.Core.EntityCommandExecutionException' occurred in EntityFramework.SqlServer.dll

堆栈跟踪:

 at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
   at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
   at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
   at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)

{"A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)"}

最佳答案

根据 ewahner 的建议和对错误原因的小型研究,它主要与 Sql Server 限制有关(从服务器读取日志可能会给出一些提示),一个可能的解决方案是使用批量插入。我用过这个extension在一个项目中,结果非常好(比添加实体的经典 EF 保存快几十倍)。

如果你的存储过程很复杂(做一些计算,在其他表中保存一些数据等)你仍然可以使用批量插入:

  • 生成标识符(插入 session 标识符)
  • 使用生成的标识符作为批标识符,通过 BulkInsert 将数据保存在 session 表中
  • 通过提供标识符作为额外参数来调用过程
  • 从 session 表中删除数据(最好通过在工作时间以外运行的作业,因为删除对表的使用有很大影响)

关于c# - 使用 Entity Framework 进行多次插入会导致 => 物理连接不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33012668/

相关文章:

c# - 使用 C# 在 access 2007 中更改链接表的源表

c# - 数据库; "Cannot add a PRIMARY KEY column"-异常

c# - Entity Framework MySQL tinyint(1) System.Boolean.Parse FormatException

c++ - 使用 C++ sql.h 备份 SQL 数据库

sql-server - NOT IN 的 SQL 优化代码

c# - 如何删除对象而不在 EF 中检索它

c# - 我可以对以任何顺序唯一的多个属性设置主键/唯一约束吗?

c# - Entity Framework 代码首先 : 1:0. .1 更改外键位置

c# - 在 C# 中获取 Flash 文件的运行时间的最可靠方法是什么?

sql - SQL Server 2008 上的 TableDiff 实用程序有哪些替代方案?