Linq ordering smartdates

Linq ordering smartdates

Old forum URL: forums.lhotka.net/forums/t/7690.aspx


Nemisis posted on Monday, September 28, 2009

Rocky exposes smartdates in the books as follows, using managed fields

Private Shared FailedDateProperty As BSLPropertyInfo(Of SmartDate) = RegisterProperty(New BSLPropertyInfo(Of SmartDate)("FailedDate"))
Public ReadOnly Property FailedDate() As String
    Get
        Return GetPropertyConvert(Of SmartDate, String)(FailedDateProperty)
    End Get
End Property

But if you do this, then linq seems to order the dates on a string basis, not a date basis.  Has anyone else got this problem and if so how do you get around it?

richardb replied on Monday, September 28, 2009

In my Info type objects I just exposed them as SmartDates and the list object containing them binds and sorts fine.

Could try just returning the Smrtdate property as a smartdate.

Public Property AccreditedDate() As SmartDate
   Get
      
Return _accreditedDate
   End Get
   Friend Set(ByVal value As SmartDate)
      _accreditedDate = value
   End Set
End Property

 

JonnyBee replied on Monday, September 28, 2009

Hi,

Expose the SmartDate as both a string and DateTime property

You'll want the string property to use the flexibility of input and the DateTime property for sorting.

/jonnybee

Nemisis replied on Monday, September 28, 2009

this would mean having two properties called different things returning the same data,which doesnt really appeal to me, didnt know if i was missing something completely obvious.

What are other people returning in their business librarys, Strings or SmartDates?  How do you cope with sorting?  Please let me know

RockfordLhotka replied on Monday, September 28, 2009

The reason for exposing the value as a string is so you can bind it to a simple TextBox control. This allows for very flexible entry of values by the user. My goal was to enable date entry similar to what you find in Quicken or Microsoft Money - and this is my personal preference for date entry. I want to be able to type 't' and get today's date, or '10/3' to get Oct 3, 2009.

And of course SmartDate lets the TextBox be empty - which corresponds to an empty date value.

If your application requires that sort of flexible date entry then you should follow the pattern I show in the book. And you might also expose a SmartDate property for sorting.

If your application doesn't work this way - perhaps you always use a datetime picker (which means you can't have empty dates) or some other UI control that binds to a DateTime. In that case I wouldn't use SmartDate at all, because you aren't using any of its features.

Or you might use one of the datetime picker controls that understands SmartDate (and thus empty date values) - in which case you can expose the property as type SmartDate, not string.

Nemisis replied on Monday, September 28, 2009

Rocky,  Thanks for this.  We currently use the method in the book and expose all our dates as strings, as we do need an emptydate value.  We have wrote our own datepickers, that accept a string as well, so this all works perfectly.  It is just the problem of sorting the data as at the moment, it sorts like it is a string.

I think that the easiest option is going to be, to expose it as a smartDate as change our components to accept the smartdate type, then we will have everything we need.

Thanks all

JonnyBee replied on Monday, September 28, 2009

Hi,

You should be aware of possible problems with validation rules.

Your databinding will be "DateProperty.Text" or "DateProperty.Value" - and that is the key the ErrorProvider/ErrorWarnInfoProvider uses to check for ValidationError on the property.  Most likely your validation rules ar for "DateProperty".

So from my own experience I would not recommend to expose the SmartDate as the property. IOW - broken rules on your SmartDate property is likely to not be shown correctly in your UI.

mbblum replied on Monday, September 28, 2009

Prior to LINQ, a class implmentingthe IComparer interface was used to build a custom Compare. Then Sort would be provided the class implementing IComparer to use to perform a custom sort.

Can LINQ use/specify an IComparer class for sorting? Or is there something similar in LINQ?

Nemisis replied on Tuesday, September 29, 2009

I must admit, once you start thinking of changing databound controls to read DateProperty.Text or DateProperty.Value and changing all validationRules etc, it makes me not want to change from a String property to a SmartDate.

"Prior to LINQ, a class implmentingthe IComparer interface was used to build a custom Compare. Then Sort would be provided the class implementing IComparer to use to perform a custom sort. "

Can LINQ use/specify an IComparer class for sorting? Or is there something similar in LINQ?
That would be great if there is going to have to google it and see what i can find.  Does anyone know if this is possible and have they used it.

Thanks for the tip

Jack replied on Tuesday, September 29, 2009

In your LINQ statement you should be able to do whatever transformations you want and still return whatever result set you want.  You should be able to return your smartDate but order on x=>x.Smartdate.Date

 

This returns a subset of child data where my keys match ordered by the date where ScheduledDate is a SmartDate

 

return ParentScheduleExplorer.ScheduleDetailList.Where(x => x.ParentScheduleId == ScheduleId).OrderBy(x =>x.ScheduledDate.Date);

 

From: Nemisis [mailto:cslanet@lhotka.net]
Sent: September-29-09 6:06 AM
To: jaddington@alexandergracie.com
Subject: Re: [CSLA .NET] Linq ordering smartdates

 

I must admit, once you start thinking of changing databound controls to read DateProperty.Text or DateProperty.Value and changing all validationRules etc, it makes me not want to change from a String property to a SmartDate.

"Prior to LINQ, a class implmentingthe IComparer interface was used to build a custom Compare. Then Sort would be provided the class implementing IComparer to use to perform a custom sort. "

Can LINQ use/specify an IComparer class for sorting? Or is there something similar in LINQ?
That would be great if there is going to have to google it and see what i can find.  Does anyone know if this is possible and have they used it.

Thanks for the tip


Nemisis replied on Tuesday, September 29, 2009

Yes this would work, but i am returning a string not a smartdate

Jack replied on Tuesday, September 29, 2009

then convert your string to date in the orderby clause.

 

pseudo code

 

OrderBy(x => Convert.DateTime(x.MyStringDate));

 

From: Nemisis [mailto:cslanet@lhotka.net]
Sent: September-29-09 8:43 AM
To: jaddington@alexandergracie.com
Subject: Re: [CSLA .NET] RE: Linq ordering smartdates

 

Yes this would work, but i am returning a string not a smartdate


Nemisis replied on Tuesday, September 29, 2009

Jack, i dont know much about linq, but this sounds good and possibly exactly what i need! Thanks

Not sure if this will make sense, but since you seem to know abit about linq etc, do you know if you can override the sort command using linq?

Basically i have a grid control within my web page that uses linq to order the data, i can override the sort command on the grid and get the field name, order etc that the grid is going to order the list in, but i didnt know if i could somehow make a sort override against my BO, so that instead of the grid attempting to sort my list by strings, i could use your code above?

Sorry if this doesnt make to much sense

mbblum replied on Tuesday, September 29, 2009

Small but important detail, you are looking to override the comparer. Check Linq's OrderBy() to see if a comparer can be specified, similar to Sort().

But you may not need that. Modify Jack's suggestion (using cond?true:false syntax) to check for IsNullOrEmpty on the date string, when true use DateTime.Min (or Max if empties are after other dates) else the date string.

Hopefully that will get the desired result.

Jack replied on Tuesday, September 29, 2009

Not sure that I really follow but generally what I do to get around any of these things where I can't do an override at runtime is just add pseudo properties to my BO so that I can use them whenever I want.

 

The code I provided just does an initial sort on the underlying collection.  If you stick it in a grid and click on the column header then its going to use the column/property to sort.

 

So if you add a:

 

public DateTime MyStringDateSort { get{return Convert.DateTime(MyStringDate);}}

 

to you BO then you can always use that whenever you need to provide a field for sorting.  You could then replace your MyStringDate in the override of the sort command with MyStringDateSort

 

 

 

From: Nemisis [mailto:cslanet@lhotka.net]
Sent: September-29-09 9:24 AM
To: jaddington@alexandergracie.com
Subject: Re: [CSLA .NET] RE: RE: Linq ordering smartdates

 

Jack, i dont know much about linq, but this sounds good and possibly exactly what i need! Thanks

Not sure if this will make sense, but since you seem to know abit about linq etc, do you know if you can override the sort command using linq?

Basically i have a grid control within my web page that uses linq to order the data, i can override the sort command on the grid and get the field name, order etc that the grid is going to order the list in, but i didnt know if i could somehow make a sort override against my BO, so that instead of the grid attempting to sort my list by strings, i could use your code above?

Sorry if this doesnt make to much sense


Copyright (c) Marimer LLC