treykc78 / dapper-dot-net

Automatically exported from code.google.com/p/dapper-dot-net
Other
0 stars 0 forks source link

char(1) not mapped to char (SQL Server 2008R2) #42

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I have a class containing "char Delimiter" field that is represented in the 
database by char(1) column. It is used for CSV parsing.

Using a simple select query, I expect to map some rows from database to a list 
of such objects.

Instead, I'm receiving an exception:

System.Data.DataException: Error parsing column 18 (Delimiter=, - String) ---> 
System.InvalidCastException: Specified cast is not valid.

To reproduce:

1. Create class "Test" with field "public char Delimiter"
2. Create table "Test" with column "Delimiter char(1)"
3. Connection.Query<Test>("SELECT * FROM Test");

If it's not a bug, I would appreciate a suggestion, how to handle this using 
Dapper. Thanks.

Original issue reported on code.google.com by marcin.s...@expertsender.com on 4 Jul 2011 at 2:59

GoogleCodeExporter commented 9 years ago
Oh, I forgot: I'm using latest available NuGet package (Dapper 1.4).

Original comment by marcin.s...@expertsender.com on 4 Jul 2011 at 3:01

GoogleCodeExporter commented 9 years ago
Sounds like something that should work; I'm happy to take a look later

Original comment by marc.gravell on 4 Jul 2011 at 3:04

GoogleCodeExporter commented 9 years ago
Let me post a temporary workaround I did:

I have devised a solution for "custom" mapping of selected columns. It could 
come in handy if you encounter problem such as mine or if you want to map some 
columns in different way than default.

The trick is to use Dapper's multimapping.

When there is only one column you want to map differently, you may map it to 
simple type, e.g:

var sql = "SELECT Id, Foo, Bar AS Id FROM Test";
Connection.Query<Test, string, Test>(sql, (test, bar) => 
{
  test.Bar = bar.ToLower();
  return test;
});

As you can see, "Bar" column is mapped to separate string and ToLowered before 
injecting into Test object.
Note that "Bar" column is named as "Id", so Dapper can differentiate it as new 
entity.

If you have multiple columns you want to exclude from "normal" mapping, you can 
map them to dynamic object:

var sql = "SELECT Id, 1 AS Id, Foo, Bar FROM Test";
Connection.Query<Test, dynamic, Test>(sql, (test, fooBars) => 
{
  test.Foo = fooBars.Foo.ToLower();
  test.Bar = fooBars.Bar.ToLower();
  return test;
});

Note that fake Id column is added to select, so Dapper can split the record 
into two entities.

Of course, this method is cumbersome, because you always have to list all 
columns you want to select, instead of using "*", but it works.

Still, I'd rather use my generic DAOs for these char fields, so looking forward 
for new version. ;)

Original comment by marcin.s...@expertsender.com on 4 Jul 2011 at 5:58

GoogleCodeExporter commented 9 years ago
Fixed in code; not yet deployed

Original comment by marc.gravell on 4 Jul 2011 at 9:48

GoogleCodeExporter commented 9 years ago
fixed in code, to be pushed to nuget later today

Original comment by sam.saff...@gmail.com on 11 Jul 2011 at 11:30