Thanks for bearing with me. I am getting there (maybe)....
I change the SupervisorId property to use the SqlInt32 type as such:
Public Property SupervisorId() As System.Data.SqlTypes.SqlInt32
Get
Return m_SupervisorId
End Get
Set(ByVal Value As System.Data.SqlTypes.SqlInt32)
m_SupervisorId = Value
End Set
I was then able to assign integer values or even a null value to the
property:
Account.SupervisorId = New SqlInt32(2) 'assign constant 2
Account.SupervisorId = SqlInt32.Null
However, you suggested using the DataReader.GetInt32 method instead of the
GetSqlInt32 method. I assume that you are suggesting that I use the Int32
datatype rather than the SqlInt32 datatype. It looks to me like Int32 does
not allow the storage of a null value to it. In fact, I believe Int32 and
Integer are synonymous, so not being able to store a NULL value is no
surprise.
Anyway, I felt fine with gong with the sqlInt32 data type. I even read that
SQLTypes are faster when getting data from a SQL Server database. (Not sure
if you were saying SqlTypes were slower and to use native VB types like
Integer/Int32 instead)
However,when taking the above approach and using SqlInt32 data type for the
property data type, I ran into a problem.
We use Stored Procs to get data from a database. The dataset returned is
passed across tiers and the a dataset is used to populate a colelction of
objects. Then, a user may update the object. What I do is move the data
from the object BACK to the dataset, convert it to XML using the Ds.writeXML
method, and pass it to a Stored Proc to process it.
The problem is that the SupervisorID column in the table, I find, is of type
INT32 not SqlInt32, as I kind of expected since it is coming from a SQL Svr
database. When I move the value of the SqlInt32 Supervisior property to this
dataset column, I get a conversion error (SqlInt32 cant be converted to
Int32)
drwAccount.Item("SupervisorId") = Account.SupervisorId
since the Supervisor column is of type Int32, not SqlInt32, which is the
type of the property.
Strange! It seems that the Int32 datatable can store a DBNULL.Value in it,
but the SqlInt32 datatype used for the property cannot, we can only store
SqlInt32.Null. So I end up having to perform these crazy conversion back and
forth:
'Moving data from the dataset to the object property
Private m_SupervisorId as SqlInt32
If IsDBNull(drvAccountSkpi.Item("SupervisorId")) Then
m_SupervisorId = SqlInt32.Null
Else
m_SupervisorId = New
SqlInt32(CType(drvAccountSkpi.Item("SupervisorId"), Integer))
End If
'Moving data from the object property to the dataset
If Account.SupervisorId.IsNull Then
DataRow.Item("SupervisorId") = System.DBNull.Value
Else
DataRow.Item("SupervisorId") =
Int32.Parse(Account.SupervisorId.ToString)
End If
This is ugly as hell. There has to be a better way.
And how would one convert from a SqlInt32 to an Int32 or Integer?
This seems like a bad way to do it:
Int32.Parse(Account.SupervisorId.ToString)
Have you r eached your tolerance point, Ken? How about some more tips?
"Ken Dopierala Jr." <kdopierala2@wi.rr.com> wrote in message
news:%235HhnlHlFHA.2852@TK2MSFTNGP15.phx.gbl...
Hi Chad,
I would just use the DataReader.GetInt32() function instead of the
GetSqlInt32() function. Unless there is something very specific you need
out of it. If there is something very specific then change this line:
Account.SupervisorId = CInt(2)
To:
Account.SupervisorId = New SqlInt32(2)
That will allow you to assign a regular integer to a SQL type integer. Note
that if you are using these things in large loops I would definitely move to
native .Net types like Integer as they are a little over twice as fast.
When I build my objects I use native .Net types and when I read from a
dataread I just use GetInt32(). You can even use
CInt(DataReader("ColumnName")) then also. Good luck! Ken.

Signature
Ken Dopierala Jr.
For great ASP.Net web hosting try:
http://www.webhost4life.com/default.asp?refid=Spinlight
If you sign up under me and need help, email me.
"Chad" <chad.dokmanovich@unisys.com> wrote in message
news:dcdpo7$odh$1@trsvr.tr.unisys.com...
When I said that "the Value property on my object cannot be made the default
property" I meant that in VB.NET, unlike VB6, you could not have a default
property unless the property accepts a parameter.
In the IntergerNullable class I created, the Value property accepted no
params. I believe you suggested that it should. I am confused as to what you
are trying to accomplish by adding a param.
Secondly, I see you are correct about the SQLDataReader.GetSqlInt32 method,
it does accept as its param, the index of the field that you want to get as
a SqlInt32 datatype. However, I feel my question remains.
Please consider the example below. I have a class Account, which has three
properties, AccountId, AccountMgrId and SupervisorId. The first is a
required integer property. The other properties I would like to allow a NULL
value or an integer value only. The AccountMgrId property is implemented to
use my custom class IntegerNullable, which is a class that I created to
"extend" the Integer so it can also accept NULL values. The problem I have
with it is that, because unlike the native INTEGER type, it is a true object
and it is awkward to refer to the value of an IntegerNullable type by
refering to its Value property rather than just the object itself. However,
I do not consider this horrible. In fact, I kind of think that Microsft
maybe should have implemented Integers as a real object for consistancy, but
I suspect there is alot to this subject. Anyway...
The SupervisorID I implemented in the Account class as a SqlInt32 datatype.
I can move a value from the SupervisorId database column to this property
using this command:
Account.SupervisorId = DataReader.GetSqlInt32(1)
but in the GUI layer, how do I move a value, say the Integer value "2" to
the Account.Supervisor property?
As you see below, when I attempt to do this, I get the error 'System.DBNull'
cannot be converted to 'System.Data.SqlTypes.SqlInt32'.
I get the same error if I try to use the CTYPE or the CINT functions:
Account.SupervisorId = CInt(2) 'Value of type 'Integer' cannot be converted
to 'System.Data.SqlTypes.SqlInt32'.
Account.SupervisorId = CType(2, Integer) 'Value of type 'Integer' cannot be
converted to 'System.Data.SqlTypes.SqlInt32'.
Cor wrote:
A value is placed on the stack and holds (a) value(s)
An object is placed on the managed heap. If its address to that is null,
than it Is Nothing or as you wrote (Null).
I hope that this gives an idea?
That wasn't enough help for me. Perhaps you can clarify this point for me?
Anyway, I think my IntegerNullable class will work fine, I just think it is
a little awkward.
You comments are welcomed.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim Account As New Account(AccountId:=1)
Dim i As Integer
Account.AccountMgrId = New IntegerNullable(2)
If Account.AccountMgrId.IsNull Then
System.Diagnostics.Debug.WriteLine("The Account has no Manager")
Else
System.Diagnostics.Debug.WriteLine("The Manager's ID is " &
Account.AccountMgrId.Value)
End If
Dim DataReader As SqlDataReader
Account.SupervisorId = DBNull.Value 'System.DBNull' cannot be
converted to 'System.Data.SqlTypes.SqlInt32'.
Account.SupervisorId = 2 'System.DBNull' cannot be converted to
'System.Data.SqlTypes.SqlInt32'.
End Sub
Public Class Account
'An account must have an ID but it may or may not have an Account
Manager
Private m_AccountID As Integer
Private m_AccountMgrId As IntegerNullable
Private m_SupervisorId As System.Data.SqlTypes.SqlInt32
Public Sub New(ByVal AccountID As Integer)
m_AccountID = AccountID
m_AccountMgrId = New IntegerNullable
End Sub
Public Property AccountId() As Integer
Get
Return m_AccountID
End Get
Set(ByVal AccountId As Integer)
m_AccountID = AccountId
End Set
End Property
Public Property AccountMgrId() As IntegerNullable
Get
Return m_AccountMgrId
End Get
Set(ByVal AccountMgrId As IntegerNullable)
m_AccountMgrId = AccountMgrId
End Set
End Property
Public Property SupervisorId() As System.Data.SqlTypes.SqlInt32
Get
Return m_SupervisorId
End Get
Set(ByVal Value As System.Data.SqlTypes.SqlInt32)
m_SupervisorId = Value
End Set
End Property
End Class
Option Strict On
Option Explicit On
Public Class IntegerNullable
Inherits System.Object
Implements System.Data.SqlTypes.INullable
Private mintValue As Integer
Private mblnIsNull As Boolean
Public Sub New()
mintValue = Nothing
mblnIsNull = True
End Sub
Public Sub New(ByVal Value As Integer)
mintValue = Value
mblnIsNull = True
End Sub
Public Property Value() As Integer
Get
If mblnIsNull Then
Throw New Exception("Value property is not accessible when
isNull is True. Use IsNull property to test before accessing Value
property")
End If
Return mintValue
End Get
Set(ByVal Value As Integer)
mintValue = Value
mblnIsNull = False
End Set
End Property
Public ReadOnly Property IsNull() As Boolean Implements
System.Data.SqlTypes.INullable.IsNull
Get
Return mblnIsNull
End Get
End Property
Public Sub Nullify()
mblnIsNull = True
mintValue = Nothing
End Sub
End Class
Chad - 31 Jul 2005 01:53 GMT
This is probably a netter way to convert from a SQLInt32 to an Int32, but this is still a mess just to store a NULL value
SqlInt32 to Int32 Conversion
Converts the supplied SqlInt32 structure to an integer.
[Visual Basic]
returnValue = SqlInt32.op_Explicit(x)
[C#]
public static explicit operator int(
SqlInt32 x
);
[C++]
public: static int op_Explicit();
[JScript]
> Thanks for bearing with me. I am getting there (maybe)....
>
[quoted text clipped - 279 lines]
>
> End Class