Handling DateTime Database Nulls


Author
Message
Jeff Pagley
Jeff Pagley
Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)Advanced StrataFrame User (641 reputation)
Group: StrataFrame Users
Posts: 223, Visits: 893
Hi SF Team,

For all datetime data fields I have set up in the BOMapper "Return Alternate on Null/Set Null...." and NULL Replacement Value = #1/1/1900# (for smalldatetime data type)

Therefore as I understand this feature, when the field value is NULL when saving the record, it writes a NULL value back to the database and not 1/1/1900.

However, the BO object is writing 1/1/1900 back to the database and not the NULL value. 

What I found when stepping through the BO logic using the debugger that if I don't set the value of the BO field to #1/1/1900# then the Set property within the BO code is never executed.  Therefore, when saving the record, the Get property logic retrieves the 1/1/1900 value of the BO.field and writes it to the database.

So what I have to do is in the BO_BeforeSave event I have placed the following code:

if BO.DateTimeFieldName = #1/1/1900# then BO.DateTimeFieldName = #1/1/1900#

This piece of code forces the Set property of the field in the BO to execute.  Now when the BO writes the value to the database, the Get property logic returns the NULL value and writes the NULL value back to the database.

This seems like a bug to me or am I doing something wrong in the BO Mapper configuration?

Thanks!

Replies
Edhy Rijo
E
StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
JJP,

Being new, I decided to do more test and change my DateTime fields to SmallDateTime and surprisingly, I am not able to save any record, since SF is adding a default datetime of '01/01/1800 00:00:00'  and this is not valid range for a SmallDateTime field.  I guess this may be a bug with a SmallDateTime field, setting my fields to DateTime, I don't have any problems. 

Hope this clear, confirm your issues.

BusinessLayerException
  An error occurred while saving an the data to the server.
DataLayerSavingException
  SqlDbType.SmallDateTime overflow.  Value '01/01/1800 00:00:00' is out of range.  Must be between 1/1/1900 12:00:00 AM and 6/6/2079 11:59:59 PM.
OverflowException
  SqlDbType.SmallDateTime overflow.  Value '01/01/1800 00:00:00' is out of range.  Must be between 1/1/1900 12:00:00 AM and 6/6/2079 11:59:59 PM.

Source     : MicroFour StrataFrame Business

Stack Trace:
   at System.Data.SqlClient.TdsParser.WriteValue(Object value, MetaType type, Int32 actualLength, Int32 encodingByteSize, Int32 offset, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at MicroFour.StrataFrame.Data.DbDataSourceItem.InternalExecuteReader(DbCommand Command, Boolean IsTransactional, String TransactionKey)
   at MicroFour.StrataFrame.Data.SqlDataSourceItem.UpdateRow(QueryInformation QueryInfo, DataRow RowToUpdate, ConcurrencyExceptionHandler ConcurrencyHandler, AddRowErrorHandler RowErrorHandler, Boolean RecreateCommand)
   at MicroFour.StrataFrame.Data.DbDataSourceItem.UpdateRow(QueryInformation QueryInfo, DataRow RowToUpdate, ConcurrencyExceptionHandler ConcurrencyHandler, AddRowErrorHandler RowErrorHandler)
   at MicroFour.StrataFrame.Data.DataLayer.UpdateDataTableThread(Object ThreadParams)
   at MicroFour.StrataFrame.Data.DataLayer.SaveByForm(DataTable TableToSave, Boolean Transactional, String TransactionKey)
   at MicroFour.StrataFrame.Business.BusinessLayer.SaveByForm(Boolean Transactional, String TransactionKey)
   at MicroFour.StrataFrame.UI.Windows.Forms.BaseForm.Save(Boolean Transactional, String TransactionKey)
   at MicroFour.StrataFrame.UI.Windows.Forms.MaintenanceFormToolStrip.cmdSave_Click(Object sender, EventArgs e)
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativewindow.WndProc(Message& m)
   at System.Windows.Forms.Nativewindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)



Edhy Rijo

Edhy Rijo
E
StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)StrataFrame VIP (6.4K reputation)
Group: StrataFrame Users
Posts: 2.4K, Visits: 23K
Hi JJP,

I think I got this figured out Tongue

The DatetimePicker control has a property named NullDateValue, set its value to 1/1/1900 and problem should be fixed, also make sure the property ClearOnNuLL is set to True (Default) to display a blank date in the DateTimePicker control.

Looking at the SF source code I noticed that they are setting this property to 1/1/1800 by default and that is why I got the range error before.



Edhy Rijo

StrataFrame Team
S
StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)StrataFrame Developer (6.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
I think the problem you're experiencing, jjp, has to do with the AllowNullValuesOnNewRow property.  The property defaults to False, so all fields within the business object are initialized for a new record.  For a SmallDateTime, this means 01/01/1900.  So, the value within the BO gets set as soon as you Add() a new record to the business object.  OK, now the "Set Null on Alternate" property only works through the Set() of the property, so if the field within the CurrentDataTable is initialized, it never goes through the Set(), so the field never gets set to NULL, it just stays as 01/01/1900. 

So, you'll want to either set the AllowNullValuesOnNewRow property to False so that all fields are left as DBNull.Value, or in your SetDefaultValues(), you'll want do this to that field:

Me.CurrentRow("fieldname") = DBNull.Value

Otherwise, the field will have 01/01/1900 in it from the get-go.

GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...





Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search