Dostosowywanie CommandTimeout w Dapper.NET?

92

Próbuję uruchomić kopie zapasowe SQL za pomocą procedury składowanej za pośrednictwem Dapper (reszta mojej aplikacji korzysta z Dapper, więc wolałbym, aby ta część również przez nią działała). Działa dobrze, dopóki nie włączy się CommandTimeout.

using (var c = SqlConnection(connstring))
{
    c.Open();
    var p = new DynamicParameters();
    // fill out p

    c.Execute("xp_backup_database", p, commandType: CommandType.StoredProcedure);
}

Jedyne ustawienie CommandTimeout, o którym wiem, znajduje się w SqlCommand. Czy istnieje sposób, aby to ustawić przez Dapper?

sh-beta
źródło
1
Z jakiegoś powodu nie mogę teraz odpowiedzieć na własne pytanie. Ale wydaje się, że wystarczyło dodanie nazwanego argumentu "commandTimeout: 0" do c.Execute () załatwiło to.
sh-beta

Odpowiedzi:

106

Tak, istnieje wiele wersji funkcji Wykonaj. Jeden (lub więcej) z nich zawiera parametry commandTimeout:

public static int Execute(this IDbConnection cnn, string sql, 
                dynamic param = null, IDbTransaction transaction = null, 
                            int? commandTimeout = null, CommandType? commandType = null)

Zaczerpnięte z SqlMapper.cs

jzacharuk
źródło
4
Miałem ten sam problem, ale z metodą Query, ale rozwiązanie też działało, ponieważ ma też parametr commandTimeout.
jahu
2
@DrSchizo, dlaczego nie miałby być używany, nie ma powodu, aby Async Await uniknąć Time out
Mrinal Kamboj
1
@DrSchizo Dokumentacja twierdzi, że nie jest ona używana z metodami asynchronicznymi, takimi jak BeginExecuteReader, a nie async / await. Zakładam, że dzieje się tak, ponieważ jeśli używasz BeginExecuteReader, zakłada się, że użyjesz własnej logiki limitu czasu.
jugg1es
3
Czy można ustawić ten limit czasu dla wszystkich zapytań? Próbowałem z, SqlConnection.ConnectionTimeout Propertyale mówi, że jest tylko do odczytu. Potrzebowałbym go do niektórych niestandardowych programów do migracji. Pisanie tego z każdym poleceniem jest żmudne.
Tadej
5
@jedatkinports SqlMapper.Settings.CommandTimeout Wierzę, że jest to, czego szukasz.
Shiv
59

Przykład z oryginalnego pytania z dodaną akceptowaną odpowiedzią na wypadek, gdyby ktoś chciał. (Limit czasu jest ustawiony na 60 sekund):

using (var c = SqlConnection(connstring))
{
    c.Open();
    var p = new DynamicParameters();
    // fill out p

    c.Execute("xp_backup_database", p, commandTimeout: 60, 
                                       commandType: CommandType.StoredProcedure);
}
Adrian Carr
źródło
6

Nie ma potrzeby ustawiania limitu czasu polecenia dla wszystkich zapytań / wywołań Db. Możesz ustawić globalnie, jak poniżej.

Dapper.SqlMapper.Settings.CommandTimeout = 0;

Tę właściwość statyczną można zainicjować podczas ładowania aplikacji lub w konstruktorze klasy bazy danych.

Pomaga to w usuwaniu duplikatów, a jeśli zdecydujesz się to zmienić później, możesz to zmienić raz.

Mozart Al Khateeb
źródło
0

Udało mi się rozwiązać mój problem za pomocą connection.Query ustawiając bezpośrednio limit czasu

int timeOutInSeconds = 60;
.
.
.
result = conn.Query<list>(stringQuery, new {parameters, ..}, null, true, timeOutInSeconds).ToList();
Amanda Mata
źródło