Frage

Ich ändere den Befehl von Linq-to-SQL, um ihn zu zwingen, Nolock wie dieses zu verwenden ...

if (db.Connection.State == System.Data.ConnectionState.Closed)
    db.Connection.Open();

var cmd = db.GetCommand(db.Customers.Where(p => p.ID == 1));

cmd.CommandText = cmd.CommandText.Replace("[Customers] AS [t0]", "[Customers] AS [t0] WITH (NOLOCK)");

var results = db.Translate(cmd.ExecuteReader());

Es handelt sich um eine MVC -Anwendung, daher befindet sich der DataContext im Basicontroller und wurde möglicherweise vor diesem Code und vor allem danach verwendet. Sollte ich die Verbindung in dieser Routine schließen? Oder überhaupt nicht? Oder nur, wenn ich es hier geöffnet habe?


Aktualisieren:

Ich verwende jetzt die allgemeinere Funktion (in der DataContext -Klasse), um den Befehlstext zu ändern und die Verbindung zu schließen, wenn sie hier geöffnet wurde. Und die Open wurden zum Executerader hinuntergeführt. Bisher hat es die sporadischen Deadlock -Probleme gearbeitet und reduziert. Die Ergebnisse müssen nicht nach rechts sein.

    public List<T> GetWithNolock<T>(IQueryable<T> query)
    {
        // to skip nolock, just...
        // return query.ToList();

        List<T> results = null;

        bool opened = false;

        try
        {
            if (Connection.State == System.Data.ConnectionState.Closed)
            {
                Connection.Open();

                opened = true;
            }

            using (var cmd = GetCommand(query))
            {
                cmd.CommandText = Regex.Replace(cmd.CommandText, @"((from|inner join) \[dbo.*as \[t\d+\])", "$1 with (nolock)", RegexOptions.IgnoreCase);

                results = Translate<T>(cmd.ExecuteReader()).ToList();
            }
        }
        finally
        {
            if (opened && Connection.State == System.Data.ConnectionState.Open)
            {
                Connection.Close();
            }
        }

        return results;
    }

Ich habe in der Vergangenheit festgestellt, dass die Verwendung einer Transaktion auf die empfohlene Weise dazu führt, dass die Site über Nacht keine Verbindungen ausgeht. Soweit ich weiß, ist das ein Fehler in Linq-to-SQL. Es mag Wege geben, aber ich versuche meinen Hauptcode unkompliziert zu halten. Ich muss das jetzt "einfach" tun ...

var users = GetWithNolock<User>(
  Users
  .Where(u => my query
);
War es hilfreich?

Lösung

Wenn Sie es öffnen, sollten Sie es schließen. Andere linqtosql -Operationen stimmen mit diesem Muster überein.

In meinem Code öffne ich die Verbindung bedingungslos und schließe die Verbindung in einem schließlich. Wenn mir jemand eine offene Verbindung übergeht, ist das ihre Schuld und ich schließe sie für ihn.

Sie können die Öffnung der Verbindung bis kurz vor Executereader verzögern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top