Pregunta

Estoy modificando el ComandoText de Linq a SQL para obligarlo a usar Nolock, así ...

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 una aplicación MVC, por lo que el DataContext está en el controlador base, y puede haberse utilizado antes de este código y, lo que es más importante, después. ¿Debería cerrar la conexión en esta rutina? O no en absoluto? ¿O solo si lo abrí aquí?


Actualizar:

Ahora estoy usando la función más general (en la clase DataContext) para modificar el ComandoText y cerrar la conexión si se abrió aquí. Y el Abierto ha sido trasladado al ejecutor. Hasta ahora ha estado funcionando y reduciendo los problemas esporádicos de punto muerto. Los resultados no tienen que ser de inmediato.

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

En el pasado, he encontrado que usar una transacción de la manera recomendada hace que el sitio se quede sin conexiones durante la noche. Hasta donde yo sé, ese es un error en Linq a SQL. Puede haber formas de evitarlo, pero estoy tratando de mantener mi código principal directo. Ahora "solo" tengo que hacer esto ...

var users = GetWithNolock<User>(
  Users
  .Where(u => my query
);
¿Fue útil?

Solución

Si lo abres, debes cerrarlo. Otras operaciones de Linqtosql coinciden con este patrón.

En mi código, abro incondicionalmente la conexión y cierre la conexión en un finalmente. Si alguien me pasa una conexión abierta, es su culpa y lo cierro por ellos.

Puede retrasar la apertura de la conexión hasta justo antes de Ejecutorader.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top