2
Vote

Issue with QuerySingle and custom mapping

description

I believe you have a bug in your FluentData.DbCommand.QuerySingle<TEntity>(Action<Tentity, dynamic> customMapper) method.

You call QueryHandler like this:
item = new QueryHandler<TEntity>(Data).ExecuteSingle(customMapper, null)

but that is incorrect for the "Action<Tentity, dynamic> customMapper" type.

It should be
item = new QueryHandler<TEntity>(Data).ExecuteSingle(null, customMapper)
just like it is in FluentData.DbCommand.QueryMany.

This causes code like this to not work at all:
Product products = Context.Sql(@"select * from Product where ProductId = 1")
            .QuerySingle<Product>(Custom_mapper_using_dynamic);

public void Custom_mapper_using_dynamic(Product product, dynamic row)
{
    product.ProductId = row.ProductId;
    product.Name = row.Name;
}
Inside Custom_mapper_using_dynamic, you will get an exception on the 1st line because the row object does not contain that data.

A workaround for is to use QueryMany and then just get back a List<> of size 1. But it would be better to fix QuerySingle.

comments

Anusien wrote Jan 16, 2014 at 12:17 AM

I see the same issue.

When I step in to debugger there, row is of type FluentData.DataReader. Since I'm using SQL, the InnerReader is System.Data.SqlClient.SqlDataReader. When I enumerate Results View of the Inner Reader, I get "Enumeration yielded no results".

When I use QueryMany() instead, the datatype of row is FluentData.DynamicDataReader.

wrote Apr 3, 2014 at 11:01 AM

jwhijazi wrote Sep 4, 2014 at 6:14 AM

Yes, I got the same issue, i spent almost the whole day trying to debug my code and see the problem.
The problem was with the error msg:

'object' does not contain a definition for (field name).

but if you do QueryMany<>().FirstOrDefault() its works like a charm.

But if you insist to use the QuerySingle<> then you can use custom mapping with IDataReader row like the code below:
    public static product Get_ProductInfo(int proId)
    {
        using (var _db = FluentContext.Context())
        {
            return _db.Sql(SQL.Get_ProductInfo).Parameters(proId).QuerySingle<product >(CustomMapper.Custom_mapper_product);
        }
    }


    public static void Custom_mapper_product (product _product, FluentData.IDataReader  row)
    {
        _product .product _Type = Convert.ToInt32(row.GetValue("product _Type"));
        _product .Book_Title = (string)row.GetValue("product _Title");
        _product .Book_Summary = (string)row.GetValue("product _Summary");
        _product .Book_Content = (string)row.GetValue("product _Content");
        _product .Book_Date = Convert.ToDateTime(row.GetValue("product _Date"));
    }