Как вызвать хранимую процедуру для цикла с помощью C # - PullRequest
0 голосов
/ 13 октября 2019

Я хочу вызвать хранимую процедуру в цикле, но время команды истекло при использовании запроса команды, но если использовать linq, то вызов хранимой процедуры вызывает ошибку времени выполнения:

System.Data.Entity. Core.EntityException
HResult = 0x80131501
Сообщение = Произошла ошибка при запуске транзакции на соединении провайдера. Подробности см. Во внутреннем исключении.
Source = EntityFramework

StackTrace:
в System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction (IsolationLevel изоляцияLevel) в System.Data.Entity.Core.EntityClient.EntityConnection.BeginTransaction () в System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction [T] (операция Func 1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass4b.<ExecuteFunction>b__49() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func 1) в System.Data.Entity.Core.Objects.ObjectContext.ExecuteFame (функция String, Параметры ObjectParameter []) в iTax.Models.DB_iTAXEntities1.sp_Visit_Plan_Not_Found (счет-фактура Nullable 1 operator, Nullable 1, параметры Nullable 1 client) in D:\Projects\iTAX\source code\iTax\Models\Model1.Context.cs:line 564 at iTax.Controllers.Follow_UpController.Visit() in D:\Projects\iTAX\source code\iTax\Controllers\Follow_UpController.cs:line 290 at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary 2) в System.Web.Mvc.ControllerActionInvoker.Incriptcript2.CallEndDelegate (IAsyncResult asyncResult) в System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End () в System.Web.Mvc.Async.AsyncControllerActionInves.AvSync. AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d () в System.Web.Mvc.Async.AsyncAsontc.ontSontrollerActionInvoker.AsyncInvocationWithFilters. <> c__DisplayClass46.b__3f ()

Исключение: исключение - 1: исключение: исключение - 1: исключение: исключение 1другие потоки, работающие в сеансе.

Код C #:

var form = Request.Form;
var ops = long.Parse(form["Operator"]);
var keys = form.AllKeys.Where(A=> !A.Contains("Operator")).Select(A => long.Parse(A));
var plan = M.T_Visit_Plan.Where(V => keys.Any(A => A == V.Client));

int i = 0;

foreach (var item in plan)
    M.sp_Visit_Plan_Not_Found(ops, M.T_Invoice.Where(A => A.Client == item.Client).Max(A => A.id), item.Client);

return RedirectToAction("Visit", new { Operator = ops });

Код хранимой процедуры:

ALTER PROCEDURE [dbo].[sp_Visit_Plan_Not_Found] 
    @Operator BIGINT = 0,
    @Invoice BIGINT = 0, 
    @Client BIGINT = 0
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO T_Visit (Operator, Invoice, Date, Mode, Client)
    VALUES (@Operator,@Invoice, GETDATE(), 5, @Client)

    DECLARE @Visit BIGINT

    SELECT @Visit = MAX(id) 
    FROM T_Visit

    UPDATE T_Visit_Plan
    SET Visit = @Visit
    WHERE (Client = @Client)
END

Используйте этот код, но команда времени ожидания

public static void Visit_Plan_Not_Found(long ops, long invoice, long client)
    {
        SqlConnection con = new SqlConnection(new EntityConnectionStringBuilder(ConfigurationManager.ConnectionStrings["DB_iTAXEntities1"].ConnectionString).ProviderConnectionString);
        using (con)
        {
            string query = @"INSERT INTO T_Visit
                                           (Operator, Invoice, Date, Mode, Client)
                             VALUES        (@Operator, @Invoice, GETDATE(), 5, @Client)

                             DECLARE @Visit BIGINT

                             SELECT @Visit = MAX(id) 
                             FROM T_Visit

                             UPDATE       T_Visit_Plan
                             SET                Visit = scope_identity()
                             WHERE        (Client = @Client)";

            using (SqlCommand cmd = new SqlCommand(query, con))
            {
                cmd.Parameters.Add("@Operator", SqlDbType.BigInt).Value = ops;
                cmd.Parameters.Add("@Invoice", SqlDbType.BigInt).Value = invoice;
                cmd.Parameters.Add("@Client", SqlDbType.BigInt).Value = client;

                if (cmd.Connection.State == ConnectionState.Closed) con.Open();

                cmd.ExecuteNonQuery();

                if (cmd.Connection.State == ConnectionState.Open) con.Close();
            }
        }
    }

1 Ответ

2 голосов
/ 13 октября 2019

Эта строка:

var plan = M.T_Visit_Plan.Where(V => keys.Any(A => A == V.Client));

создает запрос, но не запускает его. Затем эта строка:

foreach (var item in plan)

Запускает запрос и начинает получать результаты, но не загружает их все в память. Затем эта строка:

M.sp_Visit_Plan_Not_Found . . .

Пытается запустить хранимую процедуру на том же соединении, которое используется для получения результатов.

Исправление простое: загрузите результаты первого запроса в список перед их повторением:

var planQuery = M.T_Visit_Plan.Where(V => keys.Any(A => A == V.Client));
var plan = planQuery.ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...