Search code examples
mysqlservicestackormlite-servicestack

ServiceStack ORMLite not populating results from MySQL


I'm new to ORMLite in ServiceStack. I'm trying to query an existing MySQL database. I've created this POCO to correspond to my table layout in MySQL:

[Alias("checks")]
public class Check
{
    [AutoIncrement]
    [PrimaryKey]
    public long check_id { get; set; }
    public long room_state_id { get; set; }
    public DateTime? entry_stamp { get; set; }
    public int student_id { get; set; }
    public string reason { get; set; }
    public string comments { get; set; }
    public long check_type_id { get; set; }
    public DateTime? check_dt { get; set; }
    public byte grace { get; set; }
    public DateTime curfew_dt { get; set; }
    public int excused_by { get; set; }
    public string status { get; set; }
    public int points { get; set; }
    public string check_class { get; set; }
    public int leave_id { get; set; }
    public DateTime night_of { get; set; }
    public DateTime violation_dt { get; set; }
    public string excused_reason { get; set; }
    public DateTime? excused_dt { get; set; }
    public sbyte imported { get; set; }
}

Here's the MySQL table definition

CREATE TABLE checks (
  check_id bigint(11) NOT NULL AUTO_INCREMENT,
  room_state_id bigint(11) NOT NULL DEFAULT 0,
  entry_stamp datetime DEFAULT NULL,
  student_id int(11) NOT NULL DEFAULT 0,
  reason varchar(60) DEFAULT NULL,
  comments text DEFAULT NULL,
  check_type_id bigint(20) NOT NULL DEFAULT 0,
  check_dt datetime DEFAULT NULL,
  grace tinyint(4) UNSIGNED NOT NULL DEFAULT 0,
  curfew_dt datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  excused_by int(11) NOT NULL DEFAULT 0,
  status char(1) NOT NULL DEFAULT '',
  points int(11) NOT NULL DEFAULT 0,
  check_class char(2) NOT NULL DEFAULT '',
  leave_id int(11) NOT NULL DEFAULT 0,
  night_of date NOT NULL DEFAULT '0000-00-00',
  violation_dt datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  excused_reason varchar(255) NOT NULL DEFAULT '',
  excused_dt datetime DEFAULT '0000-00-00 00:00:00',
  imported tinyint(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (check_id),
  INDEX check_class (check_class),
  INDEX check_dt (check_dt),
  INDEX check_type_id (check_type_id),
  INDEX excused_by (excused_by),
  INDEX leave_id (leave_id),
  INDEX night_of (night_of),
  INDEX status (status),
  INDEX student_id (student_id)
)

And I'm trying to get some results using:

    public object Get(GetChecks request)
    {
        return new GetChecksResponse { Results = Db.Select<Check>(q => q.student_id == request.StudentId ) };
    }

When I test this, I get a table of results with the right number of rows, but none of the data is populated (all fields in all rows are blank or 0, except for datetimes which have a nonsensical date). How can I find why ORMLite is not populating my POCOs?

UPDATE:

Logging shows a lot of DateTime conversion errors:

2016-01-23 15:35:53.5869|ERROR|OrmLiteWriteCommandExtensions|MySql.Data.Types.MySqlConversionException: Unable to convert MySQL date/time value to System.DateTime

at MySql.Data.Types.MySqlDateTime.GetDateTime() at MySql.Data.MySqlClient.MySqlDataReader.GetValue(Int32 i) at MySql.Data.MySqlClient.MySqlDataReader.GetValues(Object[] values) at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.PopulateWithSqlReader[T](T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader reader, Tuple`3[] indexCache, Object[] values)


Solution

  • If you add logging:

    LogManager.LogFactory = new ConsoleLogFactory();
    

    You'll see the error:

    ERROR: System.FormatException: Input string was not in a correct format.
       at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
       at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
       at System.SByte.Parse(String s, NumberStyles style, NumberFormatInfo info)
       at ServiceStack.Text.Common.DeserializeBuiltin`1.<>c.<GetParseFn>b__4_2(String value) in C:\src\ServiceStack.Text\src\ServiceStack.Text\Common\DeserializeBuiltin.cs:line 51
       at ServiceStack.OrmLite.OrmLiteConverterExtensions.ConvertNumber(IOrmLiteDialectProvider dialectProvider, Type toIntegerType, Object value) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\IOrmLiteConverter.cs:line 151
       at ServiceStack.OrmLite.OrmLiteConverterExtensions.ConvertNumber(IOrmLiteConverter converter, Type toIntegerType, Object value) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\IOrmLiteConverter.cs:line 115
       at ServiceStack.OrmLite.Converters.IntegerConverter.FromDbValue(Type fieldType, Object value) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\Converters\IntegerConverters.cs:line 25
       at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.PopulateWithSqlReader[T](T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader reader, Tuple`3[] indexCache, Object[] values) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\OrmLiteWriteCommandExtensions.cs:line 343
    

    The issue is that the MySql ADO.NET Provider returns tinyint(1) as a bool so you can resolve the issue by changing it to a bool:

    public bool imported { get; set; }