Question

Je modifier la CommandText de LINQ to SQL pour le forcer à utiliser nolock, comme ça ...

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

Il est une application MVC, de sorte que le DataContext est dans le contrôleur de base, et peut avoir été utilisé avant ce code, et plus important encore, après. Dois-je fermer la connexion dans cette routine? Ou pas du tout? Ou que si je l'ai ouvert ici?


Mise à jour:

J'utilise maintenant la fonction plus générale (dans la classe DataContext) pour modifier le CommandText et fermer la connexion si elle a été ouverte ici. Et l'ouverture a été déplacé vers le bas à la ExecuteReader. Jusqu'à présent, il a travaillé et de réduire les problèmes sporadiques de blocage. Les résultats ne doivent pas être en haut à droite à la seconde.

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

J'ai trouvé dans le passé que l'utilisation d'une opération de la manière recommandée provoque le site de manquer de connexions du jour au lendemain. Pour autant que je sache, c'est un bogue dans LINQ to SQL. Il peut y avoir des façons de contourner, mais je suis en train de garder mon principal simple de code. Je maintenant « juste » dois faire ...

var users = GetWithNolock<User>(
  Users
  .Where(u => my query
);
Était-ce utile?

La solution

Si vous l'ouvrez, vous devez le fermer. D'autres opérations de ce modèle LinqToSql correspondent.

Dans mon code, j'ouvrir inconditionnellement la connexion et fermer la connexion dans un finalement. Si quelqu'un me passe une connexion ouverte, qui est de leur faute et j'arrive à fermer pour eux.

Vous pourriez retarder l'ouverture de la connexion juste avant ExecuteReader.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top