Insight.Database - 将 Insert 与 OpenWithTransaction 结合使用

tum*_*999 3 c# insight.database visual-studio-2015

第一个问题:)

我是使用 Insight.Database 库的新手,但我认为我正在以正确的方式使用它。我正在同一解决方案的另一个项目中的 XUnit 测试中运行下面的(简化的)代码。异常是在 connTran.Insert 行上引发的,如果我在 CATCH 块中的日志记录功能上中断并查看异常中的消息,它会给出错误 error 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 企业版。调试器也表现不正常 - 将鼠标悬停在变量等上在事务“内部”时不起作用。我在 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;
}
Run Code Online (Sandbox Code Playgroud)

实体对象如下所示:

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; }
}
Run Code Online (Sandbox Code Playgroud)

tum*_*999 5

嗯...再多一些乱七八糟地研究一下 Insight 源代码,我就解决了原来的问题,并遇到了更多问题。我将在这里发布我的发现,以防 Insight 作者看到。

我最初问题的答案是将我的 TRY..CATCH 重组为 USING 内部 - 这可能是显而易见的,也许不是,但现在我知道了:) 所以我的代码变成了这样:

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;
   } 
}
Run Code Online (Sandbox Code Playgroud)

请注意,我还可以摆脱在 using 之外声明 connTran 变量。

由于我使用的是 SQL 2008,因此我热衷于将表值参数与插入存储过程一起使用。这给了我下一个令人头疼的问题——这可能与过时的文档有关。

doco 声明代码如下:

connTran.Insert("usp_Lookup_InsertHeader", entity);
Run Code Online (Sandbox Code Playgroud)

将插入记录,然后将新的标识值映射回实体,假设返回的 id 字段和实体属性名称匹配(它们确实如此)。Insert 存储过程的签名如下:

CREATE PROCEDURE [dbo].[usp_Lookup_InsertHeader] 
    @lookupHeader [lookupHeaderType] READONLY
Run Code Online (Sandbox Code Playgroud)

Insight 一直抱怨“lookupHeader”参数没有定义,所以我最终在 doco 的其他地方偶然发现了一些东西,将我的代码变成了这样:

connTran.Insert("usp_Lookup_InsertHeader", entity, new { lookupHeader = entity });
Run Code Online (Sandbox Code Playgroud)

现在 Insight 很高兴:)

第三个问题变成了日期时间值。

CsysLastUpdateDate实体中的财产被定义为DateTime?。在 TVP 的 SQL 类型中,该CsysLastUpdateDate字段定义为DateTime。在我的测试中,我CsysLastUpdateDateDateTime.Now

通过观察 SQL Profiler,我发现 Insight 发布的 SQL 文本包含毫秒,现在是日期时间值的字符串表示形式。下面是此文本的示例,其中包含字符串日期时间 - '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)
Run Code Online (Sandbox Code Playgroud)

当 SQL 尝试执行该文本来创建 TVP 时,它因日期时间转换问题而出错。如果我手动编辑日期时间字符串中的毫秒并执行文本,则 TVP 会正确创建。

经过更多的尝试,我发现将CsysLastUpdateDateType 中的字段声明为字段DateTime2,Insight 发送的 SQL 可以正常执行,并且 Insert 工作得很好。

我不确定我是否发现了错误,或者这些只是新手学习,但我希望这对下一个人有帮助:)