it-swarm.com.de

Entity Framework - Wie lautet der aktuelle Zeitlimitwert für Befehle

Ich verwende Entity Framework 5 und möchte den Timeoutwert des Befehls kennen.

Dazu konvertiere ich das dbContext-Objekt in einen ObjectContext und greife auf die CommandTimeout-Eigenschaft zu.

int ? currentCommandTimeout = ((IObjectContextAdapter)dbContext).ObjectContext.CommandTimeout;

Der aktuelle Wert dieser Eigenschaft ist null. Dies bedeutet, dass das aktuelle Befehlszeitlimit der Standardwert des zugrunde liegenden Anbieters ist.

  1. Wer ist der zugrunde liegende Anbieter? 
  2. Wie kann ich in diesem Fall (über EF-Code) den aktuellen Befehls-Timeout-Wert lesen?

MSDN ObjectContext CommandTimeout-Eigenschaftsreferenz

BEARBEITEN: Vielen Dank, dass Sie erläutert haben, wie Sie das Befehlszeitlimit festlegen und den Standardwert für das Befehlszeitlimit in der Dokumentation finden. Die Frage bleibt jedoch offen. Wie können Sie, falls möglich, den Befehl Timeout-Wert im Standardfall über EF lesen.

17
Oren

Von MSDN,

  • Die Eigenschaft CommandTimeout ruft den Timeout-Wert für alle Objektkontextoperationen in Sekunden ab oder legt diesen fest.
  • Ein null-Wert gibt an, dass der Standardwert des zugrunde liegenden Providers verwendet wird.

Wenn Sie sie also nicht explizit durch Code festlegen oder in Ihrer Verbindungszeichenfolge übergeben (in MySQL), ist dies der Standardwert Ihres Providers.

Wenn Sie einen Wert ungleich Null für CommandTimeout anzeigen möchten, müssen Sie ihn in connectionString übergeben oder durch Code setzen.

Wer ist der zugrunde liegende Anbieter?

Der zugrunde liegende Provider ist derjenige, den Sie in Ihrer Verbindungszeichenfolge als providerName übergeben.

<connectionStrings>
  <clear />
  <add name="Name" 
   providerName="System.Data.ProviderName" 
   connectionString="Valid Connection String;" />
</connectionStrings>

Hier ist System.Data.ProviderName Ihr zugrunde liegender Anbieter.

Wenn Sie MySql oder MS Sql verwenden, können Sie laut MySql-Dokumentation und MSDN

  • Der Standardwert ist 30 secs
  • Ein Wert von 0 zeigt eine unbestimmte Wartezeit an und sollte vermieden werden.

    Hinweis : 

Das Standardbefehlszeitlimit kann bei MySQL-Datenbankanbietern mithilfe des Verbindungszeichenfolgenattributs Default Command Timeout geändert werden.

18
Bhushan Firake

Wenn Sie SQLServer verwenden, beträgt das Standardzeitlimit für Befehle 30 Sekunden.

SqlCommand.CommandTimeout-Eigenschaft

4
Jason Massey

Das sollte funktionieren

var ctx = new DbContext();
ctx.Database.CommandTimeout = 120;
4
afr0
  1. Wer ist der zugrunde liegende Anbieter?

Für die Verbindung zu einer beliebigen Datenbank und zum Auslösen von SQL-Abfragen benötigen Sie einen Mechanismus oder einen Vermittler (Sie können sagen), der die Kommunikationssemantik verschiedener Aktionen versteht, die beim Abfeuern einer Abfrage ausgeführt werden müssen, z. Befehl erstellen, Verbindung herstellen, Verbindungszeitüberschreitung erledigen, erneut versuchen usw.

Alle diese Verantwortlichkeiten werden von Providern für die Datenbank übernommen, zu der Sie eine Verbindung herstellen möchten. Diese Anbieter haben unterschiedliche Implementierungen und Klassen w.r.t. die Umgebung (C #, Java, Python, Perl usw.), von der aus Sie eine Verbindung herstellen. Um eine Verbindung zu einer MySQL-Datenbank herzustellen, haben Sie verschiedene Anbieter für Java, .net oder die Python-Programmierwelt.

  1. Wie kann ich in diesem Fall (über EF-Code) den aktuellen Befehls-Timeout-Wert lesen?

Nee. Das ist nicht möglich. Wenn Sie sich die dbContext.Database.CommandTimeout -Eigenschaft genau ansehen, ist sie vom Typ int?. Die Logistik, diese Eigenschaft als nullable int zu behalten, soll also nur den Standardwert (als null) darstellen. Entity Framework (EF) macht nichts verfügbar, bis Sie einen expliziten Wert in C # -Code festgelegt haben. Ich habe dies anhand folgender Datenbanken überprüft

  • MySQL
  • SQL Server

In beiden Fällen sehe ich, dass nach dem Erstellen des DB-Kontextobjekts die Timeout-Eigenschaft des Befehls auf null festgelegt ist. Dies legt nahe, dass der Standardwert verwendet wird, der vom zugrunde liegenden Provider bereitgestellt wird.

Aber wenn Sie es in Ihrem C # -Code einmal über die dbContext.Database.CommandTimeout -Eigenschaft auf einen Nicht-Nullwert gesetzt haben, können Sie es natürlich erneut lesen, da es sich um eine get-set-Eigenschaft für das Befehlsobjekt handelt. Es wird immer der neue Wert angezeigt, der explizit im Code festgelegt wurde. 

Wenn Sie es wieder auf null setzen, verwendet EF wieder das Standardzeitlimit des zugrunde liegenden Providers.

Verwenden von Provider-Klassen anstelle von EF-Layer: Wenn Sie den ORM-Layer des Entity-Frameworks nicht verwenden und stattdessen die Core-Klassen des Providers verwenden, können Sie den Standardwert für die Zeitüberschreitung bei der Initialisierung selbst sehen. Wie wenn ich den unten genannten Code für eine MySQL-Datenbank mit dem Standardwert für den Zeitlimit für Befehle in der Verbindungszeichenfolge selbst ausgeführt habe, wird 40 angezeigt.

private static void TestingCommandTimeOutInMySql()
        {
            string connetionString = "Server=localhost;Database=sakila;Uid=root;Pwd=Passw0rd;default command timeout=40;";
            MySqlConnection con = new MySqlConnection(connetionString);
            try
            {
                cnn.Open();
                Console.WriteLine("Connection Open ! ");
                MySqlCommand cmd = new MySqlCommand("select * from actor", con);
                var timeoutValue = cmd.CommandTimeout; //shows 40
                con.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Can not open connection ! ");
            }
        }

Wenn Sie in der Verbindungszeichenfolge nichts festlegen, wird der Standardwert 30 für MySQL angezeigt. Hier ist CommandTimeoutint, NICHT int?. EF wendet also sicherlich einige Intelligenz an, während er diese Eigenschaft von Anbieterklassen offenlegt, die schließlich von EF durch dbContext.Database.CommandTimeout verfügbar gemacht werden. EF ist nur ein Wrapper für diese Providerklassen mit zusätzlicher Intelligenz.

Einige zusätzliche Details zu Verbindungsstichen:

Für SQL Server-Anbieter: Die Verbindungszeichenfolgenformate von Microsoft SQL Server stellen keine Eigenschaften bereit, mit deren Hilfe Sie ein benutzerdefiniertes Ausführungszeitlimit für Befehle festlegen können. Das Setzen eines Wertes während der Initialisierung des SQL Server-Providers ist daher einfach nicht möglich. Sie können den Wert im C # -Code immer nach der Intantiation/Initialisierung ändern. Weitere Details finden Sie hier .

Für MySQL-Anbieter: In meinen SQL-Verbindungszeichenfolgenformaten wird das standardmäßige Timeout für Befehle explizit festgelegt. Die Details finden Sie hier . In der MySQL-Verbindungszeichenfolge können Sie einen benutzerdefinierten Standardwert für das Zeitlimit für Befehle wie folgt angeben: 

default command timeout=200;
3
RBT

So mache ich es.

ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext
int commandTimeout = objectContext.CommandTimeout 
    ?? objectContext.Connection.CreateCommand().CommandTimeout;
1
enoshixi