Insight.Database - используя Вставку с OpenWithTransaction
Первый вопрос когда-либо:)
Я новичок в использовании библиотеки Insight.Database, но я думаю, что я использую это правильно. Я запускаю (упрощенный) код ниже из теста XUnit в другом проекте в том же решении. Исключение выдается в строке с connTran.Insert, и если я прерываю функцию регистрации в блоке CATCH и смотрю сообщение в исключении, это выдает ошибку CS7069: Reference to type 'DbConnectionWrapper' claims it is defined in 'Insight.Database', but it could not be found
, но тогда отладчик также прервется в строке connTran.Rollback() с A transaction has not been created for this connection
,
Странно то, что я использовал тот же код в другом тесте в том же решении и тестовом проекте, но с плоским объектом, и он работал нормально.
Я использую Visual Studio 2015 Enterprise. Отладчик также не работает должным образом - зависание над переменными и т. Д. Не работает, пока "внутри" транзакции. Я обнаружил очень похожую проблему с github на Github, но не могу найти решение, которое я мог бы использовать.
Это код вставки, который я использую - я также пробовал connTran.Insert, но получаю тот же результат.
DbConnectionWrapper connTran = null;
try
{
using (connTran = _dbconnection.OpenWithTransaction())
{
var lookupHeader = connTran.QueryResults<Results>("usp_Lookup_InsertHeader", entity);
connTran.Commit();
}
}
catch(Exception ex)
{
logException(ex.Message);
connTran.Rollback();
throw;
}
Объект сущности выглядит так:
public class LookupEntity
{
[RecordId]
public int LookupHeaderId { get; set; }
public string LookupHeaderName { get; set; }
public string LookupHeaderDescription { get; set; }
public string LookupHeaderCategory { get; set; }
public string LookupHeaderType { get; set; }
public string LookupBPMObjectName { get; set; }
public string LookupBPMMethodName { get; set; }
public string LookupBPMInputParams { get; set; }
public string LookupBPMExtraParams { get; set; }
public string LookupBPMOutputDataSetName { get; set; }
public string LookupBPMOutputNameNode { get; set; }
public string LookupBPMOutputValueNode { get; set; }
public string LookupBPMOutputActiveNode { get; set; }
public int Active { get; set; }
public int Cache { get; set; }
public int CsysLastUpdateBy { get; set; }
public DateTime? CsysLastUpdateDate { get; set; }
public int CsysInsertBy { get; set; }
public DateTime? CsysInsertDate { get; set; }
public string CsysTimeStamp { get; set; }
public string CsysTag { get; set; }
public int CsysOwnerId { get; set; }
public string CsysOwnerType { get; set; }
public int CsysRecordStatus { get; set; }
[ChildRecords]
public List<LookupDetail> LookupDetails { get; set; }
}
1 ответ
Ну... немного больше возиться и ковыряться в исходном коде Insight, я преодолел свою первоначальную проблему и столкнулся с еще несколькими. Я собираюсь опубликовать свои выводы здесь на случай, если автор Insight взглянет.
Ответ на мою первоначальную проблему состоял в том, чтобы реструктурировать мою TRY..CATCH, чтобы она была внутри ИСПОЛЬЗОВАНИЯ - это могло быть очевидно, возможно, это не так, но теперь я знаю:) Так что мой код превратился в это:
using (var connTran = _dbconnection.OpenWithTransaction())
{
try
{
connTran.Insert("usp_Lookup_InsertHeader", entity, new { lookupHeader = entity });
connTran.Commit();
}
catch(Exception ex)
{
logException(ex.Message);
connTran.Rollback();
throw;
}
}
Заметьте, что я также могу избавиться от объявления переменной connTran вне использования.
Поскольку я использую SQL 2008, я стремился использовать параметры табличных значений с хранимой процедурой вставки. Это дало мне мой следующий головной убор - что может быть связано с устаревшей документацией.
Доко утверждает, что код такой:
connTran.Insert("usp_Lookup_InsertHeader", entity);
вставит запись и затем отобразит новое значение идентификатора обратно в сущность, предполагая, что возвращаемое поле идентификатора и имена свойств сущности совпадают (что они и делают). Хранимая процедура вставки имеет такую подпись:
CREATE PROCEDURE [dbo].[usp_Lookup_InsertHeader]
@lookupHeader [lookupHeaderType] READONLY
Insight продолжал жаловаться, что параметр "lookupHeader" не был определен, поэтому я в конце концов наткнулся на что-то еще в документе, которое превратило мой код в это:
connTran.Insert("usp_Lookup_InsertHeader", entity, new { lookupHeader = entity });
Теперь Insight счастлив:)
Тогда третьим вопросом стали значения даты и времени.
CsysLastUpdateDate
свойство объекта было определено как DateTime?
, В типе SQL для TVP CsysLastUpdateDate
поле было определено как DateTime
, В моем тесте я установил CsysLastUpdateDate
в DateTime.Now
Наблюдая за SQL Profiler, я обнаружил, что отправляемый Insight текст SQL включал миллисекунды в то, что сейчас является строковым представлением значения datetime. Ниже приведен пример этого текста со строкой datetime - "2016-06-16 18:03:32.5510000".
declare @p1 dbo.lookupHeaderType
insert into @p1 values(0,N'timbo.test',N'',N'',N'',N'',N'',N'',N'',N'',N'',N'',N'',1,1,2,'2016-06-16 18:03:32.5510000',2,'2016-06-16 18:03:32.5510000',N'',N'',1,N'cSysSite',1)
Когда SQL попытался выполнить этот текст для создания TVP, он допустил ошибку при преобразовании даты и времени. Если я вручную отредактировал миллисекунды из строки даты и времени и выполнил текст, TVP был создан правильно.
Еще немного поиграв, я обнаружил, что CsysLastUpdateDate
поле в Типе как DateTime2
SQL, который отправлял Insight, был выполнен aok, и вставка работала успешно.
Я не уверен, что я нашел ошибки или это просто новичок, но я надеюсь, что это поможет следующему человеку:)