【问题标题】:Petapoco issue with nullable SQl Server smallint and int16 in vb.net在 vb.net 中,可空 SQl Server smallint 和 int16 的 Petapoco 问题
【发布时间】:2013-05-02 17:45:11
【问题描述】:

我有一个带有视图和 smallint 字段的 SQL Server 表。视图中的所有数据都会自动从 Petapoco T4 生成器标记为可为空,因为您无法在视图中指定它。 到目前为止,我对所有其他数据类型(guid、int、tinyint、string 等)都很好,但似乎可以为空的 smallint 会导致一些问题。

VB.NET 中的 T4 生成器为 SMALLINT 字段创建这个:

    Private mPasswordResetDays As Integer?
    <Column> _
    Public Property PasswordResetDays() As Integer?
        Get
            Return mPasswordResetDays
        End Get
        Set
            mPasswordResetDays = Value
        End Set
    End Property

但是我收到一个异常:

从 'System.Int16' 转换为 'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'

在 Petapoco 线 2677:

Line 2675:       else
Line 2676:       {
Line 2677:          converter = src => Convert.ChangeType(src, dstType, null);
Line 2678:       }
Line 2679:            }

从 PetaPoco 执行的 SQL 命令非常简单:

SQL Command: SELECT UserId, AllowPersistentCookie, MinPasswordLenght,
NonAlphanumericPasswordChars, AlphanumericPassword, PasswordResetDays FROM
EVA_vw_UserLoginStatusFromRoles
WHERE UserId = @0 -> @0 [String] = "d85674ab-d389-4548-ad89-5322892ca0e2"

我认为在返回 null 的 ExecuteScalar 命令上已经注意到类似的问题,但行不同,代码也不同。

如果我将类型从 Integer 更改?到 Integer,使它们不可为空,一切正常。

有关于 Petapoco 和 SQL Server Smallints 的这个问题的提示吗?

附录:查看代码为:

SELECT     a.UserId, CAST(MIN(CAST(b.AllowPersistentCookie AS int)) AS bit) AS AllowPersistentCookie, MAX(b.MinPasswordLenght) AS MinPasswordLenght, 
                  CAST(MAX(CAST(b.NonAlphanumericPasswordChars AS int)) AS bit) AS NonAlphanumericPasswordChars, CAST(MAX(CAST(b.AlphanumericPassword AS int)) AS bit) 
                  AS AlphanumericPassword, MIN(b.PasswordResetDays) AS PasswordResetDays
FROM         dbo.EVA_UsersInRoles AS a INNER JOIN
                  dbo.EVA_Roles AS b ON a.RoleId = b.RoleId
WHERE       (DATEDIFF(day, CONVERT(date, GETUTCDATE()), a.StartDate) <= 0) AND (DATEDIFF(day, CONVERT(date, GETUTCDATE()), a.EndDate) >= 0) OR
                  (DATEDIFF(day, CONVERT(date, GETUTCDATE()), a.StartDate) <= 0) AND (a.EndDate IS NULL) OR
                  (DATEDIFF(day, CONVERT(date, GETUTCDATE()), a.EndDate) >= 0) AND (a.StartDate IS NULL) OR
                  (a.EndDate IS NULL) AND (a.StartDate IS NULL)
GROUP BY a.UserId

【问题讨论】:

    标签: vb.net nullable petapoco


    【解决方案1】:

    您使用表格生成了代码,但现在您正在从视图中获取值。 SQL 必须在视图中提示该列不可为空。

    【讨论】:

    • 据我所知,在 SQL Server 中无法将视图列表示为不可为空,但我认为这个问题与从视图而不是表中提取数据无关.问题只出现在 smallint SQL Server 数据类型上,其他数据类型都可以。因此,当直接从主表而不是视图访问可为空的 smallint 时,应该会出现同样的问题。我可以尝试报告回来,但似乎很合乎逻辑。
    • 当然。我编辑了我的主要帖子添加了视图。但正如我所说的,问题不在于视图,因为它必须返回一个可为空的 smallint,问题在于 PetaPoco 在处理可为空的 smallint/int16 时。解决方案 SQL Server 端非常简单(只需在视图中转换为 int 或更改为 int 基础表字段)但我更喜欢修复 PetaPoco ......奇怪的是,在我之前没有人可以处理可为空的 smallints :)跨度>
    • 就是这样!将函数(最小值、最大值、总和等)应用于列时,新列可能会更改结果类型
    【解决方案2】:

    此问题以及解决方案位于https://github.com/toptensoftware/PetaPoco/issues/153

    PetaPoco 需要修补:

    - converter = delegate(object src) { return Convert.ChangeType(src, dstType, null); };
    + var underlyingType = Nullable.GetUnderlyingType(dstType) ?? dstType;
    + converter = src => Convert.ChangeType(src, underlyingType, null);
    

    视图是一条红鲱鱼;您可以通过将int NULL 列返回为uint? 或类似的形式,在混凝土表上重现这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 2011-08-27
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      相关资源
      最近更新 更多