WebMatrix Database.Query с пользовательским CommandTimeout

Рассмотрим следующий TestDb с TestTable и процедурой

USE TestDb GO --DROP TABLE dbo.TestTable IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = 'TestTable') BEGIN CREATE TABLE dbo.TestTable ( RecordId int NOT NULL IDENTITY(1,1) PRIMARY KEY , StringValue varchar(50) NULL , DateValue date NULL , DateTimeValue datetime NULL , MoneyValue money NULL , DecimalValue decimal(19,4) NULL , IntValue int NULL , BitValue bit NOT NULL ) INSERT INTO dbo.TestTable SELECT 'Test', CAST(GETDATE() AS DATE), GETDATE(), 100.15, 100.0015, 100, 1 UNION SELECT NULL, NULL, NULL, NULL, NULL, NULL, 0 END GO IF EXISTS (SELECT 1 FROM sys.procedures WHERE name = 'Get_TestTable') DROP PROCEDURE dbo.Get_TestTable GO CREATE PROCEDURE dbo.Get_TestTable (@RecordId int = NULL) AS WAITFOR DELAY '00:00:30'; SELECT * FROM dbo.TestTable WHERE RecordId = ISNULL(@RecordId,RecordId); GO EXEC dbo.Get_TestTable @RecordId = NULL 

При использовании встроенного помощника запросов к базе данных WebMatrix вы можете сделать следующее:

 @{ string errorMessage = String.Empty; int? RecordId = null; IEnumerable<dynamic> rowsTestTable = null; try { using (Database db = Database.Open("TestDb")) { rowsTestTable = db.Query("EXEC dbo.Get_TestTable @[email protected]",RecordId); } } catch (Exception ex) { errorMessage = ex.Message; } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title></title> </head> <body> @if(errorMessage == String.Empty) { <table border="1"> <thead> <tr> <th>RecordId</th> <th>StringValue</th> <th>DateValue</th> <th>DateTimeValue</th> <th>MoneyValue</th> <th>DecimalValue</th> <th>IntValue</th> <th>BitValue</th> </tr> </thead> <tbody> @foreach(var row in rowsTestTable) { <tr> <td>@row["RecordId"]</td> <td>@row["StringValue"]</td> <td>@if(@row["DateValue"] != null){@Html.Raw(String.Format("{0:MM/dd/yyyy}",@row["DateValue"]));}</td> <td>@if(@row["DateTimeValue"] != null){@Html.Raw(String.Format("{0:MM/dd/yyyy hh:mm:ss.fff tt}",@row["DateTimeValue"]));}</td> <td>@if(@row["MoneyValue"] != null){@Html.Raw(String.Format("{0:c}",@row["MoneyValue"]));}</td> <td>@row["DecimalValue"]</td> <td>@row["IntValue"]</td> <td>@row["BitValue"]</td> </tr> } </tbody> </table> } <p>@errorMessage</p> <h4>No Additional Problem - On handling of DateValue</h4> @try { foreach(var row in rowsTestTable) { <p>@if(row.DateValue != null){@Html.Raw(DateTime.Parse(row.DateValue.ToString()))}</p> } } catch (Exception ex) { <p>@ex.Message</p> } <h4>No Additional Problem - On handling of MoneyValue (and other number values)</h4> @try { foreach(var row in rowsTestTable) { <p>@if(row.MoneyValue != null){@Html.Raw(Double.Parse(row.MoneyValue.ToString()))}</p> } } catch (Exception ex) { <p>@ex.Message</p> } </body> </html> 

Это дает ошибку с истечением времени ожидания, так как помощник WebMatrix Database.Query имеет установленный по умолчанию 30 секунд CommandTimeout. Есть ли способ переопределить значение по умолчанию для отдельного запроса примерно на 5 минут?

Не найдя решения, я пошел по пути создания моего собственного помощника SimpleQuery, основанного на многочисленных поисках и проверке вещей, пока я наконец не нашел ссылку на код, которую я смог понять и адаптировать.

 using System.Collections.Generic; // IEnumerable<dynamic> using System.Data; // IDataRecord using System.Data.SqlClient; // SqlConnection using System.Dynamic; // DynamicObject public class SimpleQuery { public static IEnumerable<dynamic> Execute(string connectionString, string commandString, int commandTimeout) { using (var connection = new SqlConnection(connectionString)) { using (var command = new SqlCommand(commandString, connection)) { command.CommandTimeout = commandTimeout; connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { foreach (IDataRecord record in reader) { yield return new DataRecordDynamicWrapper(record); } } connection.Close(); } } } public class DataRecordDynamicWrapper : DynamicObject { private IDataRecord _dataRecord; public DataRecordDynamicWrapper(IDataRecord dataRecord) { _dataRecord = dataRecord; } public override bool TryGetMember(GetMemberBinder binder, out object result) { result = _dataRecord[binder.Name]; return result != null; } } } 

Итак, теперь с изменениями в веб-коде для использования нового помощника SimpleQuery я могу получить почти эквивалентные результаты, но с некоторыми проблемами

 @{ string errorMessage = String.Empty; int? RecordId = null; IEnumerable<dynamic> rowsTestTable = null; try { string commandString = String.Format("dbo.Get_TestTable @RecordId={0}", RecordId == null ? "null" : RecordId.ToString()); // Problem 1: Have to use String.Format to embed the Parameters rowsTestTable = SimpleQuery.Execute(System.Configuration.ConfigurationManager.ConnectionStrings["TestDb"].ConnectionString,commandString,300); foreach(var row in rowsTestTable) { break; } // Problem 2: Have to force query execution here, so the error (if any) gets trapped here } catch (Exception ex) { errorMessage = ex.Message; } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title></title> </head> <body> @if(errorMessage == String.Empty) { <table border="1"> <thead> <tr> <th>RecordId</th> <th>StringValue</th> <th>DateValue</th> <th>DateTimeValue</th> <th>MoneyValue</th> <th>DecimalValue</th> <th>IntValue</th> <th>BitValue</th> </tr> </thead> <tbody> @foreach(var row in rowsTestTable) { <tr> @*<td>@row["RecordId"]</td>*@ <!-- Problem 3: Can't reference as row["FieldName"], so if any field names have spaces or other special characters, can't reference --> <td>@row.RecordId</td> <td>@row.StringValue</td> <td>@if(@row.DateValue != null){@Html.Raw(String.Format("{0:MM/dd/yyyy}",@row.DateValue));}</td> <td>@if(@row.DateTimeValue != null){@Html.Raw(String.Format("{0:MM/dd/yyyy hh:mm:ss.fff tt}",@row.DateTimeValue));}</td> <td>@if(@row.MoneyValue != null){@Html.Raw(String.Format("{0:c}",@row.MoneyValue));}</td> <td>@row.DecimalValue</td> <td>@row.IntValue</td> <td>@row.BitValue</td> </tr> } </tbody> </table> } <p>@errorMessage</p> <h4>Additional Problem - Unexpected handling of DateValue</h4> @try { foreach(var row in rowsTestTable) { <p>@if(row.DateValue != null){@Html.Raw(DateTime.Parse(row.DateValue.ToString()))}</p> } } catch (Exception ex) { <p>@ex.Message</p> } <h4>Additional Problem - Unexpected handling of MoneyValue (and other number values)</h4> @try { foreach(var row in rowsTestTable) { <p>@if(row.MoneyValue != null){@Html.Raw(Double.Parse(row.MoneyValue.ToString()))}</p> } } catch (Exception ex) { <p>@ex.Message</p> } </body> </html> 

Проблема 1-3 комментируется во втором веб-коде, который использует помощник SimpleQuery. Это я могу обойти, но то, с чем я все еще боюсь, – это почему NULL-проверка не обнаружена для значений Number и Date.

Я был бы рад помочь правильно их обнаружить, поэтому я могу избежать последующей ошибки при использовании Double.Parse или DateTime.Parse. Я также хотел бы оценить любые общие указатели / улучшения для помощника SimpleQuery или что-нибудь еще, что вы видите.

Заранее спасибо.

Вы можете попробовать переключиться на использование Dapper. Он имеет очень похожий синтаксис для WebMatrix.Data, может возвращать результаты как IEnumerable<dynamic> или строго типизирован, если вы предпочитаете, и позволяет переопределить тайм-аут команды для каждого запроса.

https://github.com/StackExchange/dapper-dot-net

Использование следующего при использовании моего помощника SimpleQuery работает над обнаружением Null или String.Empty, поскольку значения из моего помощника при преобразовании в ToString () поступают как String.Empty, когда они поступают из Database.Query, они возвращаются как NULL.

 @try { foreach(var row in rowsTestTable) { <p>@if(!String.IsNullOrEmpty(row.DateValue.ToString())){@Html.Raw(DateTime.Parse(row.DateValue.ToString()))}</p> } } catch (Exception ex) { <p>@ex.Message</p> } 

Поэтому, хотя это не объясняет мне, почему существует разница или как сделать мой помощник SimpleQuery более эквивалентным Database.Query, он помогает мне преодолеть ближайшую проблему.

  • Заполнение WebMatrix SQL Server Compact
  • Вставить инструкцию с выводом
  • Как подключиться к базе данных SQL Server с помощью WebMatrix?
  • Как подключиться к базе данных SQL Server и извлекать данные с помощью Razor в WebMatrix?
  • Bulk INSERT в SQL Server CE
  • Ошибка при попытке динамического удаления строки из базы данных SQL Server ce с использованием WebMatrix
  • Что значит умножить таблицу на себя и получить одно поле?
  • Имя «База данных» не существует в текущем контексте?
  • Безопасно ли использовать GetLastInsertId () для всей области на веб-страницах C # .NET с использованием среды WebMatrix?
  • Как изменить конфигурацию SQL Server по умолчанию в веб-матрице Microsoft?
  • Interesting Posts

    Как выглядит диаграмма базы данных (диаграмма ER / таблица) для измерения распределения чего-то?

    Использование переменных для asc и desc в порядке

    Sql Server Service Broker: как структурировать разговоры для простого сценария очереди?

    Любая разница в производительности между использованием переменных или констант в запросе Entity Framework?

    Как вы присоединяетесь к таблицам из двух разных экземпляров SQL Server в одном запросе SQL

    Ошибка преобразования типа данных varchar в float isnumeric = 1

    Запрос на поиск дубликатов

    Как получить результат ADO.NET SqlCommand?

    Получение следующей ошибки «Значение не входит в ожидаемый диапазон» при развертывании отчета SSRS на сайте Sharepoint 2013

    MySQL INSERT с OUTPUT, как MSSQL

    даты фильтрации

    База данных Azure SQL – индексирование 10+ миллионов строк

    SQL Server 2005 – Вставка записей с использованием строки OpenXML vs с разделителями

    Использование формата $ с сервером sql?

    Назначение имен таблицам в наборе результатов SQL Server

    Давайте будем гением компьютера.