Petapoco在vb.net中具有可空的SQl Server smallint和int16的问题

时间:2013-05-08 13:10:20

标签: vb.net nullable petapoco

我有一个带有视图和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

BUt我收到一个例外:

从'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"

我认为在ExecuteScalar命令中注意到一个类似的问题,返回null,但行也不同,代码也是如此。

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

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

ADDENDUM:视图代码为:

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

2 个答案:

答案 0 :(得分:1)

此问题加上解决方案的问题是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?或类似内容返回,在具体表格中重现此内容。

答案 1 :(得分:0)

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