Тайм-аут команд с помощью Entity Framework 4.1 Code First - PullRequest
31 голосов
/ 21 июня 2011

Как установить время ожидания команды для DbContext?

Ответы [ 5 ]

74 голосов
/ 21 июня 2011

Я нашел это решение после другого поиска Google.Вы можете получить доступ к ObjectContext для DbContext, приведя this к IObjectContextAdapter.

From http://social.msdn.microsoft.com/Forums/en-ZA/adodotnetentityframework/thread/6fe91a64-0208-4ab8-8667-d061af340994:

public class MyContext : DbContext
{
    public MyContext ()
        : base(ContextHelper.CreateConnection("my connection string"), true)
    {
        ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;
    }
}
7 голосов
/ 11 декабря 2013

Лучшим решением для более поздних версий Entity Framework является использование свойства DbContext.Database.CommandTimeout.Я думаю, что это пришло с EF 6.

0 голосов
/ 14 марта 2014

У меня была такая же проблема при запуске EntityFramework v4.4 с CodeFirstStoredProc v2.2. Обновление не было для меня вариантом, поэтому мне пришлось обновить файл CodeFirstStoredProcs.cs, чтобы он содержал новый обнуляемый параметр int, называемый «commandTimeout», в следующие 3 метода, как показано ниже.

public static ResultsList CallStoredProc<T>(this DbContext context, StoredProc<T> procedure, T data, int? commandTimeout = null)
    {
        IEnumerable<SqlParameter> parms = procedure.Parameters(data);
        ResultsList results = context.ReadFromStoredProc(procedure.fullname, parms, commandTimeout, procedure.returntypes);
        procedure.ProcessOutputParms(parms, data);
        return results ?? new ResultsList();
    }

public static ResultsList CallStoredProc(this DbContext context, StoredProc procedure, IEnumerable<SqlParameter> parms = null, int? commandTimeout = null)
    {
        ResultsList results = context.ReadFromStoredProc(procedure.fullname, parms, commandTimeout, procedure.returntypes);
        return results ?? new ResultsList();
    }

В приведенном ниже методе это условие проверки параметра и применения значения cmd.connectionTimeout.

internal static ResultsList ReadFromStoredProc(this DbContext context,
        String procname,
        IEnumerable<SqlParameter> parms = null,
        int? commandTimeout = null,
        params Type[] outputtypes)
    {
        // create our output set object
        ResultsList results = new ResultsList();

        // ensure that we have a type list, even if it's empty
        IEnumerator currenttype = (null == outputtypes) ?
            new Type[0].GetEnumerator() :
            outputtypes.GetEnumerator();

        // handle to the database connection object
        var connection = (SqlConnection)context.Database.Connection;
        try
        {
            // open the connect for use and create a command object
            connection.Open();
            using (var cmd = connection.CreateCommand())
            {
                // command to execute is our stored procedure
                cmd.CommandText = procname;
                cmd.CommandType = System.Data.CommandType.StoredProcedure;

                if (commandTimeout.HasValue)
                {
                    cmd.CommandTimeout = commandTimeout.Value;
                }

                // move parameters to command object
                if (null != parms)
                    foreach (SqlParameter p in parms)
                        cmd.Parameters.Add(p);
                //    foreach (ParameterHolder p in parms)
                //        cmd.Parameters.Add(p.toParameter(cmd));

                // Do It! This actually makes the database call
                var reader = cmd.ExecuteReader();

                // get the type we're expecting for the first result. If no types specified,
                // ignore all results
                if (currenttype.MoveNext())
                {
                    // process results - repeat this loop for each result set returned by the stored proc
                    // for which we have a result type specified
                    do
                    {
                        // get properties to save for the current destination type
                        PropertyInfo[] props = ((Type)currenttype.Current).GetMappedProperties();

                        // create a destination for our results
                        List<object> current = new List<object>();

                        // process the result set
                        while (reader.Read())
                        {
                            // create an object to hold this result
                            object item = ((Type)currenttype.Current).GetConstructor(System.Type.EmptyTypes).Invoke(new object[0]);

                            // copy data elements by parameter name from result to destination object
                            reader.ReadRecord(item, props);

                            // add newly populated item to our output list
                            current.Add(item);
                        }

                        // add this result set to our return list
                        results.Add(current);
                    }
                    while (reader.NextResult() && currenttype.MoveNext());
                }
                // close up the reader, we're done saving results
                reader.Close();
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error reading from stored proc " + procname + ": " + ex.Message, ex);
        }
        finally
        {
            connection.Close();
        }

        return results;
    }
}

Я надеюсь, что эта помощь, поскольку я искал помощь, но ничего не нашла, пока я не понял, что могу сделать это без обновления версий CodeFirstStoredProcs, что также заставляет меня обновлять EntityFramework.

0 голосов
/ 28 августа 2013

Пожалуйста, попробуйте следующий код перед выполнением любой команды DB.Следующий код требует 3/4 минуты для выполнения.Итак, CommandTimeout установить 300 (в секундах) перед выполнением команды.

public List<CollectionEfficiencyByUnitOfficeSummary> ReadCollectionEfficiencyByUnitOfficeSummary(string yearMonth, string locationCode, string reportType)
        {
            ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.CommandTimeout = 300;
            return context.CollectionEfficiencyByUnitOfficeSummary(yearMonth, locationCode, reportType).ToList();
        }
0 голосов
/ 27 июня 2011

Если вы используете SqlServer, просто добавьте это в строку подключения: "... Connect Timeout = x" Где x - время ожидания в мс.

...