Domanda

sto modificando il CommandText di LINQ to SQL per forzarlo ad utilizzare nolock, come questo ...

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());

Si tratta di un'applicazione MVC, in modo che il DataContext è nel controller di base, e potrebbe essere stato utilizzato prima di questo codice, e, soprattutto, dopo. Dovrei chiudere la connessione in questa routine? O per niente? O solo se ho aperto qui?


Aggiornamento:

Ora sto utilizzando la funzione più generale (nella classe DataContext) per modificare il CommandText, e chiudendo la connessione se è stato aperto qui. E l'apertura è stata spostata verso l'ExecuteReader. Finora ha lavorato e riducendo i problemi di stallo sporadici. I risultati non devono essere di destra-up-to-the-secondo.

    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;
    }

ho trovato in passato che utilizza una transazione nel modo consigliato fa sì che il sito a corto di connessioni durante la notte. Per quanto ne so, questo è un bug in LINQ to SQL. Ci possono essere modi intorno ad esso, ma sto cercando di mantenere il mio codice semplice principale. Io ora "solo" devo fare questo ...

var users = GetWithNolock<User>(
  Users
  .Where(u => my query
);
È stato utile?

Soluzione

Se lo si apre, si dovrebbe chiudere esso. Altre operazioni LinqToSql corrispondono a questo modello.

Nel mio codice, ho incondizionatamente aprire la connessione e chiudere la connessione in un fine. Se qualcuno mi passa una connessione aperta, che è colpa loro e mi capita di chiudere per loro.

Si potrebbe ritardare l'apertura della connessione fino a poco prima ExecuteReader.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top