DIPSAS / Dapper.Oracle

Oracle support for Dapper Micro ORM.
MIT License
113 stars 43 forks source link

Oracle Date not converting correctly to C# DateTime #22

Closed Robfrey closed 5 years ago

Robfrey commented 5 years ago

Below I am returning an object with a DateTime object in it.

object:

 public class MyObject
{
    public DateTime CreatedDate { get; set; }
}

Repository method:

 public IEnumerable<MessageBroadcast> GetLatest(MyRequest request)
    {

        try
        {
            using (IDbConnection connection = Connection)
            {

                var parameters = new OracleDynamicParameters();
                parameters.Add("OutOutputData", null, OracleMappingType.RefCursor, ParameterDirection.Output);
                parameters.Add("userid", request.UserId, OracleMappingType.Varchar2, ParameterDirection.Input);
                parameters.Add("count", request.Count, OracleMappingType.Decimal, ParameterDirection.Input);
                return connection.Query<MessageBroadcast>("MyStoredProcedure", parameters, commandType: CommandType.StoredProcedure);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

Test Method

[Fact]
    public void MyMethod_ShouldReturnLatest()
    {
        //Arrange
        var request = new MyRequest
        {
            UserId = "12345",
            Count = 5

        };

        var expected = new MyObject
        {
           CreatedDate = new DateTime(2019, 02, 06, 04, 05, 07),
        };

        //Act
        var actual = _sut.GetLatest(request);

        //Assert

        var actualSingle = actual.OrderBy(x => x.CompanyId).First();
        actualSingle.CreatedDate.ShouldBe(expected.CreatedDate);

    }

The date I get back is 1/1/0001 00:00:00 Instead of the expected date.

epaulsen commented 5 years ago

I don't think this is a bug on our end. What you get back from the stored procedure is DateTime.MinValue, which indicates that Dapper could not map property name on MessageBroadCast class to column in result set returned from stored procedure.

DateTime mapping is working properly, just verified this using the following test:

public class OracleActualTests
{
    [Fact]
    public void DateTimeTest()
    {
        using (OracleConnection connnection = new OracleConnection("MyOracleConnectionString"))
        {
            connnection.Open();

            DateTime expected = new DateTime(2015,5,15,8,30,25);
            var result = connnection.QuerySingle<DataObject>("SELECT 42 as IntValue, TO_DATE('2015/05/15 8:30:25', 'YYYY/MM/DD HH:MI:SS') AS DateTime from DUAL");

            result.IntValue.Should().Be(42);
            result.DateTime.Should().BeCloseTo(expected,TimeSpan.FromHours(1));  // One hour off to allow different Time Zones on DB and local machine            

            connnection.Close();    
        }                        
    }
}

public class DataObject
{
    public int IntValue { get; set; }
    public DateTime DateTime { get; set; }
}

However, mapping database fields to business objects is something not covered by this package, for that I would recommend Dapper FluentMapper: https://dapper-tutorial.net/dapper-fluentmap