Results 1 to 13 of 13

Thread: Dealing with Nothing In IComparer

  1. #1

    Thread Starter
    Frenzied Member IanRyder's Avatar
    Join Date
    Jan 2013
    Location
    Healing, UK
    Posts
    1,232

    Dealing with Nothing In IComparer

    Hi All,

    I Feel like I am missing something simple and I would appreciate your advice.

    I am creating a simple Sort class to be used on a Generic List that has been populated from the execution of a Stored Procedure from an SQL Database via the Entity Framework. Easy Enough.

    However, when I come to sort the List which is bound via a BindingSource to a DataGridView I feel like I have gone “way over the top” from a code point of view to deal with Null Values (Nothing in VS) returned from the database. As an example, which works fine, here is what I have done so far for two fields, one field being “SortCode” with NO Null values and the second field being VatNo which DOES have Null values:-

    vb.net Code:
    1. Friend Class SortVATandAccNoColumns
    2.   Implements IComparer(Of sp_EuroBilling_NewCustomerAccNoAndVatDetails_Result)
    3.  
    4.   Private _strFieldName As String
    5.   Private _sortDirection As SortOrder
    6.   Public Sub New(ByVal strFieldName As String, ByVal sortDirection As SortOrder)
    7.     _strFieldName = strFieldName
    8.     _sortDirection = sortDirection
    9.   End Sub
    10.  
    11.   Public Function Compare(x As sp_EuroBilling_NewCustomerAccNoAndVatDetails_Result, y As sp_EuroBilling_NewCustomerAccNoAndVatDetails_Result) As Integer Implements IComparer(Of sp_EuroBilling_NewCustomerAccNoAndVatDetails_Result).Compare
    12.     Select Case _strFieldName
    13.       Case "SortCode"
    14.         If _sortDirection = SortOrder.Ascending Then
    15.           Return x.SortCode.CompareTo(y.SortCode)
    16.         Else
    17.           Return y.SortCode.CompareTo(x.SortCode)
    18.         End If
    19.       Case "VatNo"
    20.         If _sortDirection = SortOrder.Ascending Then
    21.           If x.VatNo Is Nothing AndAlso y.VatNo Is Nothing Then
    22.             Return 0
    23.           ElseIf Not x.VatNo Is Nothing AndAlso y.VatNo Is Nothing Then
    24.             Return 1
    25.           ElseIf x.VatNo Is Nothing AndAlso Not y.VatNo Is Nothing Then
    26.             Return -1
    27.           Else
    28.             Return x.VatNo.CompareTo(y.VatNo)
    29.           End If
    30.         Else
    31.           If x.VatNo Is Nothing AndAlso y.VatNo Is Nothing Then
    32.             Return 0
    33.           ElseIf Not x.VatNo Is Nothing AndAlso y.VatNo Is Nothing Then
    34.             Return -1
    35.           ElseIf x.VatNo Is Nothing AndAlso Not y.VatNo Is Nothing Then
    36.             Return 1
    37.           Else
    38.             Return y.VatNo.CompareTo(x.VatNo)
    39.           End If
    40.         End If
    41.       Case Else
    42.         Return -1
    43.     End Select
    44.   End Function
    45. End Class

    When I started writing this class I just had a gut feeling that I should have been able to use Generics or Nullable variables to deal with these issues but for one reason or another I cannot get them incorporated into the Sort class and I just get the feeling that I have missed something obvious here. Not seeing the “Wood for the Trees” so to speak.

    So, the simple questions are “Am I over complicating this checking for Nothing here in the VatNo Case?” or “is there a simpler way to code this which just seems to be eluding me at the moment?”

    Many thanks to all who provide any suggestions.

    Kind regards,

    Ian

    NB, there are many more fields to be added to the class which will have Null values and VatNo is just one of them.

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,043

    Re: Dealing with Nothing In IComparer

    One thing to note is that you don't really care about the sort direction. Consider what you were doing in this code:

    Code:
    If _sortDirection = SortOrder.Ascending Then
              Return x.SortCode.CompareTo(y.SortCode)
            Else
              Return y.SortCode.CompareTo(x.SortCode)
            End If
    What's the difference between the two lines in real terms? If X = Y then all options will return 0. When X > Y then the return will be 1 in the first case and -1 in the second, but the sorting routine will order them based on ascending or descending. You haven't really done anything except guarantee that they will ALWAYS sort in ascending order. The comparison is expecting that you return some measure of whether the first measure is greater or less than the second, but you return whether the second measure is greater or less than the first when the sort order is descending.

    EDIT: I kind of missed the actual question. How can you sort Nothing in any way? Nothing values can sort always before or always after, but that's about it. So, you could simply say that if X is Nothing always return -1, regardless of Y, and if X is not Nothing while Y IS Nothing, then always return 1. That reduces the options by a fair amount.
    My usual boring signature: Nothing

  3. #3
    Lively Member
    Join Date
    Sep 2013
    Posts
    117

    Re: Dealing with Nothing In IComparer

    Null <> Nothing

    If the Null is from the DB then use DBNull, or IsDBNull.
    No where does it state the return value have to be (-1,0,1), only the value 0 has to mean both are same.

    < 0 Lower / Before
    = 0 Equal
    > 0 Higher / After
    Last edited by AdamPanic2013; Jul 21st, 2014 at 12:03 PM.

  4. #4
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Dealing with Nothing In IComparer

    Actually if both x and y are nothing you return zero. If just x is nothing return -1 otherwise return 1. This puts the nothings first.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  5. #5
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,538

    Re: Dealing with Nothing In IComparer

    There is a difference between Null and Nothing, and they are not interchangeable... Nothing means it doesn't exist... not that the value doesn't exist, but the field itself doesn't exist. But with Null, the field DOES exist, it just does not have a specific value.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  6. #6
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Dealing with Nothing In IComparer

    @tg - I believe be said he was taking the DB nulls and representing them as NOTHING on the VB client side - or I missed what he said. It's one or the other

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  7. #7
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,538

    Re: Dealing with Nothing In IComparer

    I considered that except for this line:
    a code point of view to deal with Null Values (Nothing in VS) returned from the database.
    He seemed to equate the two... and then looking at the code reveals this:
    Code:
    If x.VatNo Is Nothing AndAlso y.VatNo Is Nothing Then
    which really only checks if the fields are nothing (of course they won't be nothing because the field will exist) ... but it's really the value the OP should be comparing.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  8. #8

    Thread Starter
    Frenzied Member IanRyder's Avatar
    Join Date
    Jan 2013
    Location
    Healing, UK
    Posts
    1,232

    Re: Dealing with Nothing In IComparer

    Hi All,

    Many thanks for all the comments so far. Not had time to digest any as yet, buried with other stuff at the moment, but I will do in due course and come back with any comments.

    Cheers,

    Ian

  9. #9
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Dealing with Nothing In IComparer

    Quote Originally Posted by szlamany View Post
    Actually if both x and y are nothing you return zero. If just x is nothing return -1 otherwise return 1. This puts the nothings first.
    Just to clarify...

    This should really read: "If just x is nothing return -1 otherwise if y is nothing return 1. "

    If both x and y are not nothing you do a STRING.COMPARE to get the -1, 0 or 1 that the comparer wants.

    btw - here's a comparer I wrote 5 years ago...

    Code:
        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
                            Implements System.Collections.IComparer.Compare
            Dim returnVal As Integer = -1
            returnVal = [String].Compare(CType(x,  _
                            ListViewItem).SubItems(col).Text, _
                            CType(y, ListViewItem).SubItems(col).Text)
            ' Determine whether the sort order is descending.
            If order = SortOrder.Descending Then
                ' Invert the value returned by String.Compare.
                returnVal *= -1
            End If
    
            Return returnVal
        End Function
    It does not do you NOTHING processing - just an example

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  10. #10

    Thread Starter
    Frenzied Member IanRyder's Avatar
    Join Date
    Jan 2013
    Location
    Healing, UK
    Posts
    1,232

    Re: Dealing with Nothing In IComparer

    Hi All,

    By Shaggy Hiker
    You haven't really done anything except guarantee that they will ALWAYS sort in ascending order.
    Not true SH. I pass a sort direction to the Comparer and then X compared to Y always sorts Ascending and Y compared to X always sorts Descending.

    By Shaggy Hiker
    I kind of missed the actual question. How can you sort Nothing in any way? Nothing values can sort always before or always after, but that's about it. So, you could simply say that if X is Nothing always return -1, regardless of Y, and if X is not Nothing while Y IS Nothing, then always return 1. That reduces the options by a fair amount.

    By Szlamany
    This should really read: "If just x is nothing return -1 otherwise if y is nothing return 1. "
    Thanks SH & Szlamany, I knew I was missing some easy points.

    By AdamPanic2013
    No where does it state the return value have to be (-1,0,1), only the value 0 has to mean both are same.
    This is the requirement of a Sort Method on a List when using a Comparer.

    By Szlamany
    Actually if both x and y are nothing you return zero. If just x is nothing return -1 otherwise return 1. This puts the nothings first.
    Yes agreed, my extra bit in the code is to additionally sort the contents of the fields.

    By AdamPanic2013
    If the Null is from the DB then use DBNull, or IsDBNull.

    By techgnome
    There is a difference between Null and Nothing, and they are not interchangeable... Nothing means it doesn't exist... not that the value doesn't exist, but the field itself doesn't exist. But with Null, the field DOES exist, it just does not have a specific value.

    which really only checks if the fields are nothing (of course they won't be nothing because the field will exist) ... but it's really the value the OP should be comparing.
    I wish it were that simple Guys. To delve into the whole Null vs Nothing debate I ultimately think that this is to do with how Entity Framework 6 deals with Null values returned from a Database through the execution of a stored procedure.

    Using Datatables populated through some SQL execution routine I agree that you would check for null values in the Datatables with the appropriate methods but in the case of EF6 and a Stored Procedure it definitely sets the field to Nothing when null values are encountered which has the “knock on” effect of causing an “object reference not set to an instance of an object” when a null value (Nothing) is encountered and hence the resulting If statements in the Sort routine.

    By Szlamany
    btw - here's a comparer I wrote 5 years ago...
    Nice trick on the Descending portion of your code. Never thought to do just an Ascending Sort test and then multiple the result by -1.

    Thanks for all the knowledge everyone.

    Cheers,

    Ian

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,043

    Re: Dealing with Nothing In IComparer

    All this time I assumed that it was the sort routine that made use of ascending or descending comparisons. In that understanding, you compare the first item to the second item and get a result. The sort routine decides whether to put item A ahead of or after item B based on that comparison, and the only responsibility of the comparison is to return a value that indicated whether A was greater, less than, or equal to, B. It seems absurd to me that the sort routine would require the comparison routine to return A > B in one case and A < B in the other. The comparison should just compare the two, the sort routine should do the sorting based on that comparison. After a bit of searching, it does appear that such is not the case. I guess I've always only sorted in one direction. Still seems wrong, though. It does present an interesting possibliity, of course. Sorting ascending and sorting descending, when it comes to classes, could be performed on different fields such that the two sort orders bore no resemblance to each other at all.
    My usual boring signature: Nothing

  12. #12
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: Dealing with Nothing In IComparer

    If you are sorting on multiple columns it gets even more complicated as you enter the world of ASCENDING for some columns and DESCENDING for other.

    Back in my pre-PC days you would SUBTRACT each CHARACTER of sort data from CHR(255) to get the descending sort. Or from 99999999 if sorting a DATE for instance.

    99999999 - 20140101 = 79859898
    99999999 - 20140102 = 79859897

    Now you have a DESCENDING "sort key".

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  13. #13
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,538

    Re: Dealing with Nothing In IComparer

    Quote Originally Posted by IanRyder View Post
    I wish it were that simple Guys. To delve into the whole Null vs Nothing debate I ultimately think that this is to do with how Entity Framework 6 deals with Null values returned from a Database through the execution of a stored procedure.

    Using Datatables populated through some SQL execution routine I agree that you would check for null values in the Datatables with the appropriate methods but in the case of EF6 and a Stored Procedure it definitely sets the field to Nothing when null values are encountered which has the “knock on” effect of causing an “object reference not set to an instance of an object” when a null value (Nothing) is encountered and hence the resulting If statements in the Sort routine.
    Eeeeew! I haven't had the chance to use EF yet.... now I'm not sure... although I see some wisdom in it. But jsut because I don't agree with it doesn't mean I can't use it...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width